From 36d6873b7a27d5059aa598d2a36983f8a387a56b Mon Sep 17 00:00:00 2001 From: anthony Date: Thu, 25 Feb 2021 19:42:53 +0000 Subject: [PATCH] Make the netsurf window callback properly aware of individual tabs --- frontends/gnustep/BrowserWindowController.h | 30 ++--- frontends/gnustep/BrowserWindowController.m | 115 ++++++++++---------- frontends/gnustep/tables/window.m | 59 +++++++--- 3 files changed, 118 insertions(+), 86 deletions(-) diff --git a/frontends/gnustep/BrowserWindowController.h b/frontends/gnustep/BrowserWindowController.h index 5f2f892e2..5a2b9010b 100644 --- a/frontends/gnustep/BrowserWindowController.h +++ b/frontends/gnustep/BrowserWindowController.h @@ -18,6 +18,7 @@ struct browser_window; id searchImage; NSMutableArray *tabs; BOOL isClosing; + id activeTab; // These three are set based on the currently focused tab. id scrollView; @@ -33,25 +34,28 @@ struct browser_window; -(void)enterSearch: (id)sender; -(void)openWebsite: (Website*)aWebsite; -(void)newTab: (id)sender; --(void)newTabWithBrowser: (struct browser_window*)aBrowser; +// Returns a tab identifier that must be provided to some of the below messages. +-(id)newTabWithBrowser: (struct browser_window*)aBrowser; -(void)close: (id)sender; --(void)netsurfWindowDestroy; +-(id)initialTabId; // Browser control --(NSSize)getBrowserSize; --(NSPoint)getBrowserScroll; --(void)setBrowserScroll: (NSPoint)scroll; --(void)invalidateBrowser; --(void)invalidateBrowser: (NSRect)rect; --(void)updateBrowserExtent; --(void)placeCaretAtX: (int)x y: (int)y height: (int)height; --(void)removeCaret; +-(NSSize)getBrowserSizeForTab: (id)tab; +-(NSPoint)getBrowserScrollForTab: (id)tab; +-(void)setBrowserScroll: (NSPoint)scroll forTab: (id)tab; +-(void)invalidateBrowserForTab: (id)tab; +-(void)invalidateBrowser: (NSRect)rect forTab: (id)tab; +-(void)updateBrowserExtentForTab: (id)tab; +-(void)placeCaretAtX: (int)x y: (int)y height: (int)height inTab: (id)tab; +-(void)removeCaretInTab: (id)tab; -(void)setPointerToShape: (enum gui_pointer_shape)shape; --(void)newContent; +-(void)newContentForTab: (id)tab; +-(void)setNavigationUrl: (NSString*)urlString forTab: (id)tab; +-(void)setTitle: (NSString*)title forTab: (id)tab; +-(void)netsurfWindowDestroyForTab: (id)tab; + -(void)startThrobber; -(void)stopThrobber; --(void)setNavigationUrl: (NSString*)urlString; --(void)setTitle: (NSString*)title; -(void)findNext: (NSString*)needle matchCase: (BOOL)matchCase sender: (id)sender; -(void)findPrevious: (NSString*)needle matchCase: (BOOL)matchCase sender: (id)sender; -(void)showAll: (NSString*)needle matchCase: (BOOL)matchCase sender: (id)sender; diff --git a/frontends/gnustep/BrowserWindowController.m b/frontends/gnustep/BrowserWindowController.m index e74f2632d..1a759dbdc 100644 --- a/frontends/gnustep/BrowserWindowController.m +++ b/frontends/gnustep/BrowserWindowController.m @@ -22,14 +22,16 @@ static id newTabTarget; id scrollView; id plotView; struct browser_window *browser; + id tabItem; } @end @implementation TabContents --(id)initWithScroll: (id)scroll plot: (id)plot browser: (struct browser_window *)brows { +-(id)initWithScroll: (id)scroll plot: (id)plot browser: (struct browser_window *)brows tabItem: (NSTabViewItem*)aTabItem { if ((self = [super init])) { scrollView = scroll; plotView = plot; browser = brows; + tabItem = aTabItem; } return self; } @@ -42,14 +44,18 @@ static id newTabTarget; -(struct browser_window *)browser { return browser; } +-(id)tabItem { + return tabItem; +} @end @interface BrowserWindowController (Private) -(void)openUrlString: (NSString*)aUrlString; --(void)addTab: (struct browser_window*)aBrowser; +-(id)addTab: (struct browser_window*)aBrowser; -(void)removeTab: (struct browser_window*)aBrowser; -(void)reconfigureTabLayout; -(void)setActive: (TabContents*)tabContents; +-(Website*)currentWebsiteForTab: (id)tab; @end @implementation BrowserWindowController @@ -75,8 +81,8 @@ static id newTabTarget; NSLog(@"Browser window loaded"); } --(void)newTabWithBrowser: (struct browser_window*)aBrowser { - [self addTab: aBrowser]; +-(id)newTabWithBrowser: (struct browser_window*)aBrowser { + return [self addTab: aBrowser]; } -(void)newTab: (id)sender { @@ -124,25 +130,30 @@ static id newTabTarget; browser_window_destroy([tc browser]); } --(void)netsurfWindowDestroy { +-(void)netsurfWindowDestroyForTab: (id)tab { NSLog(@"ns destroy"); // If we're closing anyway, don't bother with tab cleanup. if (isClosing) { return; } - NSTabViewItem *selectedTab = [tabView selectedTabViewItem]; - NSInteger idx = [tabView indexOfTabViewItem: selectedTab]; + NSInteger idx = [tabView indexOfTabViewItem: [tab tabItem]]; if (idx == NSNotFound) { NSLog(@"Tab not found."); return; } - [tabView removeTabViewItem: selectedTab]; + [tabView removeTabViewItem: [tab tabItem]]; [tabs removeObjectAtIndex: idx]; if ([tabs count] < 1) { [super close]; } } +// The identifier for the first tab created. Used by window.m after creation. +// This is actually a TabContents object, for easy access to the required objects. +-(id)initialTabId { + return [tabs objectAtIndex: 0]; +} + -(void)back: (id)sender { NSLog(@"Browser backward"); [plotView back: sender]; @@ -184,33 +195,33 @@ static id newTabTarget; [self openUrlString: [aWebsite url]]; } --(NSSize)getBrowserSize { - return [[plotView superview] frame].size; +-(NSSize)getBrowserSizeForTab: (id)tab { + return [[[tab plotView] superview] frame].size; } --(NSPoint)getBrowserScroll { - return [plotView visibleRect].origin; +-(NSPoint)getBrowserScrollForTab: (id)tab { + return [[tab plotView] visibleRect].origin; } --(void)setBrowserScroll: (NSPoint)scroll { - [plotView scrollPoint: scroll]; +-(void)setBrowserScroll: (NSPoint)scroll forTab: (id)tab { + [[tab plotView] scrollPoint: scroll]; } --(void)invalidateBrowser { - [plotView setNeedsDisplay: YES]; +-(void)invalidateBrowserForTab: (id)tab { + [[tab plotView] setNeedsDisplay: YES]; } --(void)invalidateBrowser: (NSRect)rect { - [plotView setNeedsDisplayInRect: rect]; +-(void)invalidateBrowser: (NSRect)rect forTab: (id)tab { + [[tab plotView] setNeedsDisplayInRect: rect]; } --(void)updateBrowserExtent { +-(void)updateBrowserExtentForTab: (id)tab { int width, height; - browser_window_get_extents(browser, false, &width, &height); + browser_window_get_extents([tab browser], false, &width, &height); NSLog(@"set frame to size: %d, %d", width, height); - [plotView setFrame: NSMakeRect(0, 0, width, height)]; + [[tab plotView] setFrame: NSMakeRect(0, 0, width, height)]; } --(void)placeCaretAtX: (int)x y: (int)y height: (int)height { +-(void)placeCaretAtX: (int)x y: (int)y height: (int)height inTab: (id)tab { NSLog(@"Place caret... on %@", plotView); - [plotView placeCaretAtX: x y: y height: height]; + [[tab plotView] placeCaretAtX: x y: y height: height]; } --(void)removeCaret { - [plotView removeCaret]; +-(void)removeCaretInTab: (id)tab { + [[tab plotView] removeCaret]; } -(void)setPointerToShape: (enum gui_pointer_shape)shape { if (shape == lastRequestedPointer) @@ -241,19 +252,10 @@ static id newTabTarget; [[NSCursor arrowCursor] set]; } } --(void)newContent { +-(void)newContentForTab: (id)tab { NSLog(@"New content"); - struct nsurl *url = browser_window_access_url(browser); - const char *title = browser_window_get_title(browser); - if (title == NULL) { - title = ""; - } - NSString *name = [NSString stringWithCString: title]; - NSString *urlStr = [NSString stringWithCString: nsurl_access(url)]; - Website *website = [[Website alloc] initWithName: name - url: urlStr]; + Website *website = [self currentWebsiteForTab: activeTab]; [website addToHistory]; - [website release]; } -(void)startThrobber { [refreshButton setTitle: @"Stop"]; @@ -263,17 +265,16 @@ static id newTabTarget; [refreshButton setTitle: @"Refresh"]; [refreshButton setTag: 0]; } --(void)setNavigationUrl: (NSString*)urlString { +-(void)setNavigationUrl: (NSString*)urlString forTab: (id)tab { [urlBar setStringValue: urlString]; } --(void)setTitle: (NSString*)title { +-(void)setTitle: (NSString*)title forTab: (id)tab { [[self window] setTitle: title]; - NSTabViewItem *selectedTab = [tabView selectedTabViewItem]; NSString *tabTitle = title; if ([tabTitle length] > TAB_TITLE_LEN) { tabTitle = [title substringToIndex: TAB_TITLE_LEN]; } - [selectedTab setLabel: tabTitle]; + [[tab tabItem] setLabel: tabTitle]; } -(void)findNext: (NSString*)needle matchCase: (BOOL)matchCase sender: (id)sender { @@ -301,26 +302,15 @@ static id newTabTarget; } -(void)bookmarkPage: (id)sender { - struct nsurl *url = browser_window_access_url(browser); - const char *title = browser_window_get_title(browser); - if (title == NULL) { - title = ""; - } - NSString *name = [NSString stringWithCString: title]; - NSString *urlStr = [NSString stringWithCString: nsurl_access(url)]; - Website *website = [[Website alloc] initWithName: name - url: urlStr]; + Website *website = [self currentWebsiteForTab: activeTab]; CreateBookmarkPanelController *bmController = [[CreateBookmarkPanelController alloc] initForWebsite: website]; [NSApp runModalForWindow: [bmController window]]; [bmController release]; - [website release]; } -(NSString*)visibleUrl { - struct nsurl *url = browser_window_access_url(browser); - NSString *urlStr = [NSString stringWithCString: nsurl_access(url)]; - return urlStr; + return [[self currentWebsiteForTab: activeTab] url]; } -(void)openUrlString: (NSString*)aUrlString { @@ -354,7 +344,7 @@ static id newTabTarget; [self setActive: tc]; } --(void)addTab: (struct browser_window*)aBrowser { +-(id)addTab: (struct browser_window*)aBrowser { NSString *identity = @"New Tab"; NSTabViewItem *tabItem = [[NSTabViewItem alloc] initWithIdentifier: identity]; @@ -376,7 +366,7 @@ static id newTabTarget; [tabView insertTabViewItem: tabItem atIndex: num]; TabContents *tc = [[TabContents alloc] initWithScroll: newScrollView plot: - newPlotView browser: aBrowser]; + newPlotView browser: aBrowser tabItem: tabItem]; [self setActive: tc]; [tabs addObject: tc]; [tabView selectTabViewItem: tabItem]; @@ -385,6 +375,7 @@ static id newTabTarget; [tc release]; [newPlotView release]; [newScrollView release]; + return tc; } -(void)removeTab: (struct browser_window*)aBrowser { @@ -399,6 +390,20 @@ static id newTabTarget; plotView = [tabContents plotView]; scrollView = [tabContents scrollView]; browser = [tabContents browser]; + activeTab = tabContents; +} + +-(Website*)currentWebsiteForTab: (id)tab { + struct nsurl *url = browser_window_access_url(browser); + const char *title = browser_window_get_title(browser); + if (title == NULL) { + title = ""; + } + NSString *name = [NSString stringWithCString: title]; + NSString *urlStr = [NSString stringWithCString: nsurl_access(url)]; + Website *website = [[Website alloc] initWithName: name + url: urlStr]; + return [website autorelease]; } +(id)newTabTarget { diff --git a/frontends/gnustep/tables/window.m b/frontends/gnustep/tables/window.m index a2ba4a60b..6bb03bd3d 100644 --- a/frontends/gnustep/tables/window.m +++ b/frontends/gnustep/tables/window.m @@ -9,6 +9,11 @@ #import "utils/nsurl.h" #import "netsurf/mouse.h" +struct window_tab { + BrowserWindowController *window; + id tab; +}; + /********************/ /****** Window ******/ /********************/ @@ -19,32 +24,40 @@ static struct gui_window *gnustep_window_create(struct browser_window *bw, gui_window_create_flags flags) { NSLog(@"gnustep_window_create"); BrowserWindowController *controller = nil; + id tabId; if (flags & BW_CREATE_TAB) { controller = [BrowserWindowController newTabTarget]; - [controller newTabWithBrowser: bw]; + tabId = [controller newTabWithBrowser: bw]; } if (controller == nil) { controller = [[BrowserWindowController alloc] initWithBrowser: bw]; [controller loadWindow]; + tabId = [controller initialTabId]; } - return (struct gui_window*)controller; + struct window_tab *wtab = malloc(sizeof (struct window_tab)); + wtab->window = controller; + wtab->tab = tabId; + return (struct gui_window*)wtab; } // Destroy the specified window static void gnustep_window_destroy(struct gui_window *gw) { NSLog(@"gnustep_window_destroy"); - [(id)gw netsurfWindowDestroy]; + struct window_tab *wtab = (struct window_tab*)gw; + [wtab->window netsurfWindowDestroyForTab: wtab->tab]; + free(wtab); } // Trigger a redraw of the specified area, or the entire window if null static nserror gnustep_window_invalidate(struct gui_window *gw, const struct rect *rect) { NSLog(@"gnustep_window_invalidate"); + struct window_tab *wtab = (struct window_tab*)gw; if (rect == NULL) { - [(id)gw invalidateBrowser]; + [wtab->window invalidateBrowserForTab: wtab->tab]; } else { - [(id)gw invalidateBrowser: NSMakeRect(rect->x0, rect->y0, - rect->x1, rect->y1)]; + [wtab->window invalidateBrowser: NSMakeRect(rect->x0, rect->y0, + rect->x1, rect->y1) forTab: wtab->tab]; } return NSERROR_OK; } @@ -52,7 +65,8 @@ static nserror gnustep_window_invalidate(struct gui_window *gw, const struct rec // Put the current scroll offset into sx and sy static bool gnustep_window_get_scroll(struct gui_window *gw, int *sx, int *sy) { NSLog(@"gnustep_window_get_scroll"); - NSPoint scroll = [(id)gw getBrowserScroll]; + struct window_tab *wtab = (struct window_tab*)gw; + NSPoint scroll = [wtab->window getBrowserScrollForTab: wtab->tab]; *sx = scroll.x; *sy = scroll.y; return true; @@ -61,13 +75,16 @@ static bool gnustep_window_get_scroll(struct gui_window *gw, int *sx, int *sy) { // Set the current scroll offset static nserror gnustep_window_set_scroll(struct gui_window *gw, const struct rect *rect) { NSLog(@"gnustep_window_set_scroll"); - [(id)gw setBrowserScroll: NSMakePoint(rect->x0, rect->y0)]; + struct window_tab *wtab = (struct window_tab*)gw; + [wtab->window setBrowserScroll: NSMakePoint(rect->x0, rect->y0) forTab: + wtab->tab]; return NSERROR_OK; } // Put the dimensions of the specified window into width, height static nserror gnustep_window_get_dimensions(struct gui_window *gw, int *width, int *height) { - NSSize size = [(id)gw getBrowserSize]; + struct window_tab *wtab = (struct window_tab*)gw; + NSSize size = [wtab->window getBrowserSizeForTab: wtab->tab]; *width = size.width; *height = size.height; NSLog(@"gnustep_window_get_dimensions (%d, %d)", *width, *height); @@ -77,26 +94,27 @@ static nserror gnustep_window_get_dimensions(struct gui_window *gw, int *width, // Some kind of event happened static nserror gnustep_window_event(struct gui_window *gw, enum gui_window_event event) { NSLog(@"gnustep_window_event"); + struct window_tab *wtab = (struct window_tab*)gw; switch (event) { case GW_EVENT_UPDATE_EXTENT: NSLog(@"GW_EVENT_UPDATE_EXTENT"); - [(id)gw updateBrowserExtent]; + [wtab->window updateBrowserExtentForTab: wtab->tab]; break; case GW_EVENT_REMOVE_CARET: NSLog(@"GW_EVENT_REMOVE_CARET"); - [(id)gw removeCaret]; + [wtab->window removeCaretInTab: wtab->tab]; break; case GW_EVENT_NEW_CONTENT: NSLog(@"GW_EVENT_NEW_CONTENT"); - [(id)gw newContent]; + [wtab->window newContentForTab: wtab->tab]; break; case GW_EVENT_START_THROBBER: NSLog(@"GW_EVENT_START_THROBBER"); - [(id)gw startThrobber]; + [wtab->window startThrobber]; break; case GW_EVENT_STOP_THROBBER: NSLog(@"GW_EVENT_STOP_THROBBER"); - [(id)gw stopThrobber]; + [wtab->window stopThrobber]; break; default: NSLog(@"Unknown window event."); @@ -106,21 +124,26 @@ static nserror gnustep_window_event(struct gui_window *gw, enum gui_window_event } static void gnustep_window_set_title(struct gui_window *gw, const char *title) { - [(id)gw setTitle: [NSString stringWithUTF8String: title]]; + struct window_tab *wtab = (struct window_tab*)gw; + [wtab->window setTitle: [NSString stringWithUTF8String: title] forTab: + wtab->tab]; } static nserror gnustep_window_set_url(struct gui_window *gw, struct nsurl *url) { + struct window_tab *wtab = (struct window_tab*)gw; NSString *urlStr = [NSString stringWithUTF8String: nsurl_access(url)]; - [(id)gw setNavigationUrl: urlStr]; + [wtab->window setNavigationUrl: urlStr forTab: wtab->tab]; return NSERROR_OK; } static void gnustep_window_set_pointer(struct gui_window *gw, enum gui_pointer_shape shape) { - [(id)gw setPointerToShape: shape]; + struct window_tab *wtab = (struct window_tab*)gw; + [wtab->window setPointerToShape: shape]; } static void gnustep_window_place_caret(struct gui_window *gw, int x, int y, int height, const struct rect *clip) { - [(id)gw placeCaretAtX: x y: y height: height]; + struct window_tab *wtab = (struct window_tab*)gw; + [wtab->window placeCaretAtX: x y: y height: height inTab: wtab->tab]; } struct gui_window_table gnustep_window_table = {