From: Alan Third <alan@idiocy.org>
To: Andrii Kolomoiets <andreyk.mad@gmail.com>
Cc: 40200@debbugs.gnu.org, 28872@debbugs.gnu.org, aaronjensen@gmail.com
Subject: bug#40200: [PATCH v3] Fix NS frame resizing issues (bug#40200, bug#28872)
Date: Sat, 4 Apr 2020 15:17:49 +0100 [thread overview]
Message-ID: <20200404141749.GA10895@breton.holly.idiocy.org> (raw)
In-Reply-To: <20200328015657.GA66478@breton.holly.idiocy.org>
* src/nsmenu.m (update_frame_tool_bar): Remove reference to
updateFrameSize.
* src/nsterm.h: ([EmacsView updateFrameSize]):
([EmacsView setRows:andColumns:]): Remove unused
method definitions.
(NS_PARENT_WINDOW_LEFT_POS):
(NS_PARENT_WINDOW_TOP_POS): Move to nsterm.m.
* src/nsterm.m (ns_parent_window_rect): New function.
(NS_PARENT_WINDOW_LEFT_POS):
(NS_PARENT_WINDOW_TOP_POS): Move to nsterm.m and simplify.
(ns_set_offset): Fix strange behaviours when using negative values.
(ns_set_window_size):
(ns_set_undecorated):
([EmacsView windowDidResize:]):
([EmacsView windowDidExitFullScreen]):
(ns_judge_scroll_bars): Remove references to updateFrameSize.
([EmacsView dealloc]): Unset resize notification and release buffer.
([EmacsView updateFrameSize:]): Remove function.
([EmacsView windowWillResize:toSize:]): Move some code to
viewDidResize.
([EmacsView viewDidResize]): New function.
([EmacsView initFrameFromEmacs:]): Set up resize notification and move
buffer creation until after the prerequisite objects are created.
([EmacsView toggleFullScreen:]): Set frame to the size of the
contentview, not the whole window, and remove reference to
updateFrameSize.
([EmacsView setRows:andColumns:]): Remove unused method.
([EmacsView windowDidMove:]): Tidy up.
---
Once again, I think this is right. Please test and let me know how you
get on.
src/nsmenu.m | 2 -
src/nsterm.h | 15 ---
src/nsterm.m | 309 +++++++++++++++++++++++----------------------------
3 files changed, 142 insertions(+), 184 deletions(-)
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 67f9a45a40..b7e4cbd565 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -1141,8 +1141,6 @@ - (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f
}
#endif
- if (oldh != FRAME_TOOLBAR_HEIGHT (f))
- [view updateFrameSize:YES];
if (view->wait_for_tool_bar && FRAME_TOOLBAR_HEIGHT (f) > 0)
{
view->wait_for_tool_bar = NO;
diff --git a/src/nsterm.h b/src/nsterm.h
index 8396a542f7..e142dbd4f0 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -439,7 +439,6 @@ #define NS_DRAW_TO_BUFFER 1
#endif
@public
struct frame *emacsframe;
- int rows, cols;
int scrollbarsNeedingUpdate;
EmacsToolbar *toolbar;
NSRect ns_userRect;
@@ -458,11 +457,9 @@ #define NS_DRAW_TO_BUFFER 1
/* Emacs-side interface */
- (instancetype) initFrameFromEmacs: (struct frame *) f;
- (void) createToolbar: (struct frame *)f;
-- (void) setRows: (int) r andColumns: (int) c;
- (void) setWindowClosing: (BOOL)closing;
- (EmacsToolbar *) toolbar;
- (void) deleteWorkingText;
-- (void) updateFrameSize: (BOOL) delay;
- (void) handleFS;
- (void) setFSValue: (int)value;
- (void) toggleFullScreen: (id) sender;
@@ -1084,18 +1081,6 @@ #define NS_SCROLL_BAR_ADJUST_HORIZONTALLY(w, f) \
(FRAME_SCROLL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f) \
- NS_SCROLL_BAR_HEIGHT (f)) : 0)
-/* Calculate system coordinates of the left and top of the parent
- window or, if there is no parent window, the screen. */
-#define NS_PARENT_WINDOW_LEFT_POS(f) \
- (FRAME_PARENT_FRAME (f) != NULL \
- ? [FRAME_NS_VIEW (FRAME_PARENT_FRAME (f)) window].frame.origin.x : 0)
-#define NS_PARENT_WINDOW_TOP_POS(f) \
- (FRAME_PARENT_FRAME (f) != NULL \
- ? ([FRAME_NS_VIEW (FRAME_PARENT_FRAME (f)) window].frame.origin.y \
- + [FRAME_NS_VIEW (FRAME_PARENT_FRAME (f)) window].frame.size.height \
- - FRAME_NS_TITLEBAR_HEIGHT (FRAME_PARENT_FRAME (f))) \
- : [[[NSScreen screens] objectAtIndex: 0] frame].size.height)
-
#define FRAME_NS_FONT_TABLE(f) (FRAME_DISPLAY_INFO (f)->font_table)
#define FRAME_FONTSET(f) ((f)->output_data.ns->fontset)
diff --git a/src/nsterm.m b/src/nsterm.m
index 04fc051223..461431622f 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -843,6 +843,32 @@ Free a pool and temporary objects it refers to (callable from C)
}
+/* Get the frame rect, in system coordinates, of the parent window or,
+ if there is no parent window, the main screen. */
+static inline NSRect
+ns_parent_window_rect (struct frame *f)
+{
+ NSRect parentRect;
+
+ if (FRAME_PARENT_FRAME (f) != NULL)
+ {
+ EmacsView *parentView = FRAME_NS_VIEW (FRAME_PARENT_FRAME (f));
+ parentRect = [parentView convertRect:[parentView frame]
+ toView:nil];
+ parentRect = [[parentView window] convertRectToScreen:parentRect];
+ }
+ else
+ parentRect = [[[NSScreen screens] objectAtIndex:0] frame];
+
+ return parentRect;
+}
+
+/* Calculate system coordinates of the left and top of the parent
+ window or, if there is no parent window, the main screen. */
+#define NS_PARENT_WINDOW_LEFT_POS(f) NSMinX (ns_parent_window_rect (f))
+#define NS_PARENT_WINDOW_TOP_POS(f) NSMaxY (ns_parent_window_rect (f))
+
+
static NSRect
ns_row_rect (struct window *w, struct glyph_row *row,
enum glyph_row_area area)
@@ -1741,61 +1767,64 @@ Hide the window (X11 semantics)
-------------------------------------------------------------------------- */
{
NSView *view = FRAME_NS_VIEW (f);
- NSScreen *screen = [[view window] screen];
+ NSRect windowFrame = [[view window] frame];
+ NSPoint topLeft;
NSTRACE ("ns_set_offset");
block_input ();
- f->left_pos = xoff;
- f->top_pos = yoff;
+ if (FRAME_PARENT_FRAME (f))
+ {
+ /* Convert the parent frame's view rectangle into screen
+ coords. */
+ EmacsView *parentView = FRAME_NS_VIEW (FRAME_PARENT_FRAME (f));
+ NSRect parentRect = [parentView convertRect:[parentView frame]
+ toView:nil];
+ parentRect = [[parentView window] convertRectToScreen:parentRect];
+
+ if (f->size_hint_flags & XNegative)
+ topLeft.x = NSMaxX (parentRect) - NSWidth (windowFrame) + xoff;
+ else
+ topLeft.x = NSMinX (parentRect) + xoff;
- if (view != nil)
+ if (f->size_hint_flags & YNegative)
+ topLeft.y = NSMinY (parentRect) + NSHeight (windowFrame) - yoff;
+ else
+ topLeft.y = NSMaxY (parentRect) - yoff;
+ }
+ else
{
- if (FRAME_PARENT_FRAME (f) == NULL && screen)
- {
- f->left_pos = f->size_hint_flags & XNegative
- ? [screen visibleFrame].size.width + f->left_pos - FRAME_PIXEL_WIDTH (f)
- : f->left_pos;
- /* We use visibleFrame here to take menu bar into account.
- Ideally we should also adjust left/top with visibleFrame.origin. */
-
- f->top_pos = f->size_hint_flags & YNegative
- ? ([screen visibleFrame].size.height + f->top_pos
- - FRAME_PIXEL_HEIGHT (f) - FRAME_NS_TITLEBAR_HEIGHT (f)
- - FRAME_TOOLBAR_HEIGHT (f))
- : f->top_pos;
-#ifdef NS_IMPL_GNUSTEP
- if (f->left_pos < 100)
- f->left_pos = 100; /* don't overlap menu */
-#endif
- }
- else if (FRAME_PARENT_FRAME (f) != NULL)
- {
- struct frame *parent = FRAME_PARENT_FRAME (f);
+ /* If there is no parent frame then just convert to screen
+ coordinates, UNLESS we have negative values, in which case I
+ think it's best to position from the bottom and right of the
+ current screen rather than the main screen or whole
+ display. */
+ NSRect screenFrame = [[[view window] screen] frame];
- /* On X negative values for child frames always result in
- positioning relative to the bottom right corner of the
- parent frame. */
- if (f->left_pos < 0)
- f->left_pos = FRAME_PIXEL_WIDTH (parent) - FRAME_PIXEL_WIDTH (f) + f->left_pos;
+ if (f->size_hint_flags & XNegative)
+ topLeft.x = NSMaxX (screenFrame) - NSWidth (windowFrame) + xoff;
+ else
+ topLeft.x = xoff;
- if (f->top_pos < 0)
- f->top_pos = FRAME_PIXEL_HEIGHT (parent) + FRAME_TOOLBAR_HEIGHT (parent)
- - FRAME_PIXEL_HEIGHT (f) + f->top_pos;
- }
+ if (f->size_hint_flags & YNegative)
+ topLeft.y = NSMinY (screenFrame) + NSHeight (windowFrame) - yoff;
+ else
+ topLeft.y = NSMaxY ([[[NSScreen screens] objectAtIndex:0] frame]) - yoff;
+
+#ifdef NS_IMPL_GNUSTEP
+ /* Don't overlap the menu.
- /* Constrain the setFrameTopLeftPoint so we don't move behind the
- menu bar. */
- NSPoint pt = NSMakePoint (SCREENMAXBOUND (f->left_pos
- + NS_PARENT_WINDOW_LEFT_POS (f)),
- SCREENMAXBOUND (NS_PARENT_WINDOW_TOP_POS (f)
- - f->top_pos));
- NSTRACE_POINT ("setFrameTopLeftPoint", pt);
- [[view window] setFrameTopLeftPoint: pt];
- f->size_hint_flags &= ~(XNegative|YNegative);
+ FIXME: Surely there's a better way than just hardcoding 100
+ in here? */
+ boundsRect.origin.x = 100;
+#endif
}
+ NSTRACE_POINT ("setFrameTopLeftPoint", topLeft);
+ [[view window] setFrameTopLeftPoint:topLeft];
+ f->size_hint_flags &= ~(XNegative|YNegative);
+
unblock_input ();
}
@@ -1864,7 +1893,6 @@ Hide the window (X11 semantics)
[window setFrame: wr display: YES];
- [view updateFrameSize: NO];
unblock_input ();
}
@@ -1913,7 +1941,6 @@ Hide the window (X11 semantics)
so some key presses (TAB) are swallowed by the system. */
[window makeFirstResponder: view];
- [view updateFrameSize: NO];
unblock_input ();
}
}
@@ -5024,9 +5051,6 @@ in certain situations (rapid incoming events).
if ([view judge])
removed = YES;
}
-
- if (removed)
- [eview updateFrameSize: NO];
}
/* ==========================================================================
@@ -6198,6 +6222,15 @@ - (void) setWindowClosing: (BOOL)closing
- (void)dealloc
{
NSTRACE ("[EmacsView dealloc]");
+
+ /* Clear the view resize notification. */
+ [[NSNotificationCenter defaultCenter]
+ removeObserver:self
+ name:NSViewFrameDidChangeNotification
+ object:nil];
+
+ CGContextRelease (drawingBuffer);
+
[toolbar release];
if (fs_state == FULLSCREEN_BOTH)
[nonfs_window release];
@@ -7039,108 +7072,12 @@ - (BOOL)windowShouldClose: (id)sender
return NO;
}
-- (void) updateFrameSize: (BOOL) delay
-{
- NSWindow *window = [self window];
- NSRect wr = [window frame];
- int extra = 0;
- int oldc = cols, oldr = rows;
- int oldw = FRAME_PIXEL_WIDTH (emacsframe);
- int oldh = FRAME_PIXEL_HEIGHT (emacsframe);
- int neww, newh;
-
- NSTRACE ("[EmacsView updateFrameSize:]");
- NSTRACE_SIZE ("Original size", NSMakeSize (oldw, oldh));
- NSTRACE_RECT ("Original frame", wr);
- NSTRACE_MSG ("Original columns: %d", cols);
- NSTRACE_MSG ("Original rows: %d", rows);
-
- if (! [self isFullscreen])
- {
- int toolbar_height;
-#ifdef NS_IMPL_GNUSTEP
- // GNUstep does not always update the tool bar height. Force it.
- if (toolbar && [toolbar isVisible])
- update_frame_tool_bar (emacsframe);
-#endif
-
- toolbar_height = FRAME_TOOLBAR_HEIGHT (emacsframe);
- if (toolbar_height < 0)
- toolbar_height = 35;
-
- extra = FRAME_NS_TITLEBAR_HEIGHT (emacsframe)
- + toolbar_height;
- }
-
- if (wait_for_tool_bar)
- {
- /* The toolbar height is always 0 in fullscreen and undecorated
- frames, so don't wait for it to become available. */
- if (FRAME_TOOLBAR_HEIGHT (emacsframe) == 0
- && FRAME_UNDECORATED (emacsframe) == false
- && ! [self isFullscreen])
- {
- NSTRACE_MSG ("Waiting for toolbar");
- return;
- }
- wait_for_tool_bar = NO;
- }
-
- neww = (int)wr.size.width - emacsframe->border_width;
- newh = (int)wr.size.height - extra;
-
- NSTRACE_SIZE ("New size", NSMakeSize (neww, newh));
- NSTRACE_MSG ("FRAME_TOOLBAR_HEIGHT: %d", FRAME_TOOLBAR_HEIGHT (emacsframe));
- NSTRACE_MSG ("FRAME_NS_TITLEBAR_HEIGHT: %d", FRAME_NS_TITLEBAR_HEIGHT (emacsframe));
-
- cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, neww);
- rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (emacsframe, newh);
-
- if (cols < MINWIDTH)
- cols = MINWIDTH;
-
- if (rows < MINHEIGHT)
- rows = MINHEIGHT;
-
- NSTRACE_MSG ("New columns: %d", cols);
- NSTRACE_MSG ("New rows: %d", rows);
-
- if (oldr != rows || oldc != cols || neww != oldw || newh != oldh)
- {
- NSView *view = FRAME_NS_VIEW (emacsframe);
-
- change_frame_size (emacsframe,
- FRAME_PIXEL_TO_TEXT_WIDTH (emacsframe, neww),
- FRAME_PIXEL_TO_TEXT_HEIGHT (emacsframe, newh),
- 0, delay, 0, 1);
- SET_FRAME_GARBAGED (emacsframe);
- cancel_mouse_face (emacsframe);
-
- /* The next two lines set the frame to the same size as we've
- already set above. We need to do this when we switch back
- from non-native fullscreen, in other circumstances it appears
- to be a noop. (bug#28872) */
- wr = NSMakeRect (0, 0, neww, newh);
- [view setFrame: wr];
-#ifdef NS_DRAW_TO_BUFFER
- [self createDrawingBuffer];
-#endif
-
- // To do: consider using [NSNotificationCenter postNotificationName:].
- [self windowDidMove: // Update top/left.
- [NSNotification notificationWithName:NSWindowDidMoveNotification
- object:[view window]]];
- }
- else
- {
- NSTRACE_MSG ("No change");
- }
-}
- (NSSize)windowWillResize: (NSWindow *)sender toSize: (NSSize)frameSize
/* Normalize frame to gridded text size. */
{
int extra = 0;
+ int cols, rows;
NSTRACE ("[EmacsView windowWillResize:toSize: " NSTRACE_FMT_SIZE "]",
NSTRACE_ARG_SIZE (frameSize));
@@ -7277,11 +7214,6 @@ - (void)windowDidResize: (NSNotification *)notification
sz = [self windowWillResize: theWindow toSize: sz];
#endif /* NS_IMPL_GNUSTEP */
- if (cols > 0 && rows > 0)
- {
- [self updateFrameSize: YES];
- }
-
ns_send_appdefined (-1);
}
@@ -7302,6 +7234,51 @@ - (void)viewDidEndLiveResize
#endif /* NS_IMPL_COCOA */
+- (void)viewDidResize:(NSNotification *)notification
+{
+ NSRect frame = [self frame];
+ int oldw, oldh, neww, newh;
+
+ if (! FRAME_LIVE_P (emacsframe))
+ return;
+
+#ifdef NS_DRAW_TO_BUFFER
+ CGFloat scale = [[self window] backingScaleFactor];
+ oldw = (CGFloat)CGBitmapContextGetWidth (drawingBuffer) / scale;
+ oldh = (CGFloat)CGBitmapContextGetHeight (drawingBuffer) / scale;
+#else
+ oldw = FRAME_PIXEL_WIDTH (emacsframe);
+ oldh = FRAME_PIXEL_HEIGHT (emacsframe);
+#endif
+ neww = (int)NSWidth (frame);
+ newh = (int)NSHeight (frame);
+
+ NSTRACE ("[EmacsView viewDidResize]");
+
+ /* Don't want to do anything when the view size hasn't changed. */
+ if ((oldh == newh && oldw == neww))
+ {
+ NSTRACE_MSG ("No change");
+ return;
+ }
+
+ NSTRACE_SIZE ("Original size", NSMakeSize (oldw, oldh));
+ NSTRACE_SIZE ("New size", NSMakeSize (neww, newh));
+
+ change_frame_size (emacsframe,
+ FRAME_PIXEL_TO_TEXT_WIDTH (emacsframe, neww),
+ FRAME_PIXEL_TO_TEXT_HEIGHT (emacsframe, newh),
+ 0, YES, 0, 1);
+
+#ifdef NS_DRAW_TO_BUFFER
+ [self createDrawingBuffer];
+#endif
+ ns_clear_frame (emacsframe);
+ SET_FRAME_GARBAGED (emacsframe);
+ cancel_mouse_face (emacsframe);
+}
+
+
- (void)windowDidBecomeKey: (NSNotification *)notification
/* cf. x_detect_focus_change(), x_focus_changed(), x_new_focus_frame() */
{
@@ -7463,10 +7440,6 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f
maximizing_resize = NO;
#endif
-#ifdef NS_DRAW_TO_BUFFER
- [self createDrawingBuffer];
-#endif
-
win = [[EmacsWindow alloc]
initWithContentRect: r
styleMask: (FRAME_UNDECORATED (f)
@@ -7572,6 +7545,17 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f
[NSApp registerServicesMenuSendTypes: ns_send_types
returnTypes: [NSArray array]];
+#ifdef NS_DRAW_TO_BUFFER
+ [self createDrawingBuffer];
+#endif
+
+ /* Set up view resize notifications. */
+ [self setPostsFrameChangedNotifications:YES];
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector (viewDidResize:)
+ name:NSViewFrameDidChangeNotification object:nil];
+
/* macOS Sierra automatically enables tabbed windows. We can't
allow this to be enabled until it's available on a Free system.
Currently it only happens by accident and is buggy anyway. */
@@ -7601,9 +7585,8 @@ - (void)windowDidMove: sender
return;
if (screen != nil)
{
- emacsframe->left_pos = r.origin.x - NS_PARENT_WINDOW_LEFT_POS (emacsframe);
- emacsframe->top_pos =
- NS_PARENT_WINDOW_TOP_POS (emacsframe) - (r.origin.y + r.size.height);
+ emacsframe->left_pos = NSMinX (r) - NS_PARENT_WINDOW_LEFT_POS (emacsframe);
+ emacsframe->top_pos = NS_PARENT_WINDOW_TOP_POS (emacsframe) - NSMaxY (r);
// FIXME: after event part below didExitFullScreen is not received
// if (emacs_event)
@@ -7902,7 +7885,6 @@ - (void)windowDidExitFullScreen /* provided for direct calls */
{
[toolbar setVisible:YES];
update_frame_tool_bar (emacsframe);
- [self updateFrameSize:YES];
[[self window] display];
}
else
@@ -8115,11 +8097,11 @@ - (void)toggleFullScreen: (id)sender
// send notifications.
[self windowWillExitFullScreen];
- [fw setFrame: [w frame] display:YES animate:ns_use_fullscreen_animation];
+ [fw setFrame:[[w contentView] frame]
+ display:YES animate:ns_use_fullscreen_animation];
[fw close];
[w makeKeyAndOrderFront:NSApp];
[self windowDidExitFullScreen];
- [self updateFrameSize:YES];
}
}
@@ -8628,13 +8610,6 @@ - (instancetype)setMiniwindowImage: (BOOL) setMini
}
-- (void) setRows: (int) r andColumns: (int) c
-{
- NSTRACE ("[EmacsView setRows:%d andColumns:%d]", r, c);
- rows = r;
- cols = c;
-}
-
- (int) fullscreenState
{
return fs_state;
--
2.24.0
--
Alan Third
next prev parent reply other threads:[~2020-04-04 14:17 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-23 18:13 bug#40200: 28.0.50; NS: text drawing glitches in maximized frame with frame-inhibit-implied-resize Andrii Kolomoiets
2020-03-23 19:22 ` Eli Zaretskii
2020-03-23 19:47 ` Andrii Kolomoiets
2020-03-23 23:54 ` Alan Third
2020-03-25 22:28 ` bug#40200: [PATCH] Fix NS frame resizing issues (bug#40200, bug#28872) Alan Third
2020-03-26 17:35 ` bug#28872: " Andrii Kolomoiets
2020-03-26 21:21 ` bug#28872: [PATCH v2] " Alan Third
2020-03-27 9:45 ` Andrii Kolomoiets
2020-03-27 13:22 ` Andrii Kolomoiets
2020-03-28 1:56 ` Alan Third
2020-04-04 14:17 ` Alan Third [this message]
2020-04-06 6:57 ` bug#40200: [PATCH v3] " Andrii Kolomoiets
2020-04-06 18:44 ` bug#28872: [PATCH v4] " Alan Third
2020-04-07 8:14 ` bug#40200: " Andrii Kolomoiets
2020-04-16 18:24 ` bug#28872: " Alan Third
2020-04-18 1:52 ` bug#40200: " HaiJun Zhang
2020-04-18 12:07 ` Alan Third
2020-04-18 14:12 ` HaiJun Zhang
2020-04-18 15:26 ` Alan Third
2020-04-19 1:49 ` HaiJun Zhang
2020-05-03 16:26 ` Alan Third
2020-05-03 17:13 ` Filipp Gunbin
2020-05-03 18:41 ` Alan Third
2020-05-03 19:49 ` Filipp Gunbin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200404141749.GA10895@breton.holly.idiocy.org \
--to=alan@idiocy.org \
--cc=28872@debbugs.gnu.org \
--cc=40200@debbugs.gnu.org \
--cc=aaronjensen@gmail.com \
--cc=andreyk.mad@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.