Make the netsurf window callback properly aware of individual tabs

This commit is contained in:
anthony 2021-02-25 19:42:53 +00:00
parent a694bc0884
commit 36d6873b7a
3 changed files with 118 additions and 86 deletions

View File

@ -18,6 +18,7 @@ struct browser_window;
id searchImage; id searchImage;
NSMutableArray *tabs; NSMutableArray *tabs;
BOOL isClosing; BOOL isClosing;
id activeTab;
// These three are set based on the currently focused tab. // These three are set based on the currently focused tab.
id scrollView; id scrollView;
@ -33,25 +34,28 @@ struct browser_window;
-(void)enterSearch: (id)sender; -(void)enterSearch: (id)sender;
-(void)openWebsite: (Website*)aWebsite; -(void)openWebsite: (Website*)aWebsite;
-(void)newTab: (id)sender; -(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)close: (id)sender;
-(void)netsurfWindowDestroy; -(id)initialTabId;
// Browser control // Browser control
-(NSSize)getBrowserSize; -(NSSize)getBrowserSizeForTab: (id)tab;
-(NSPoint)getBrowserScroll; -(NSPoint)getBrowserScrollForTab: (id)tab;
-(void)setBrowserScroll: (NSPoint)scroll; -(void)setBrowserScroll: (NSPoint)scroll forTab: (id)tab;
-(void)invalidateBrowser; -(void)invalidateBrowserForTab: (id)tab;
-(void)invalidateBrowser: (NSRect)rect; -(void)invalidateBrowser: (NSRect)rect forTab: (id)tab;
-(void)updateBrowserExtent; -(void)updateBrowserExtentForTab: (id)tab;
-(void)placeCaretAtX: (int)x y: (int)y height: (int)height; -(void)placeCaretAtX: (int)x y: (int)y height: (int)height inTab: (id)tab;
-(void)removeCaret; -(void)removeCaretInTab: (id)tab;
-(void)setPointerToShape: (enum gui_pointer_shape)shape; -(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)startThrobber;
-(void)stopThrobber; -(void)stopThrobber;
-(void)setNavigationUrl: (NSString*)urlString;
-(void)setTitle: (NSString*)title;
-(void)findNext: (NSString*)needle matchCase: (BOOL)matchCase sender: (id)sender; -(void)findNext: (NSString*)needle matchCase: (BOOL)matchCase sender: (id)sender;
-(void)findPrevious: (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; -(void)showAll: (NSString*)needle matchCase: (BOOL)matchCase sender: (id)sender;

View File

@ -22,14 +22,16 @@ static id newTabTarget;
id scrollView; id scrollView;
id plotView; id plotView;
struct browser_window *browser; struct browser_window *browser;
id tabItem;
} }
@end @end
@implementation TabContents @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])) { if ((self = [super init])) {
scrollView = scroll; scrollView = scroll;
plotView = plot; plotView = plot;
browser = brows; browser = brows;
tabItem = aTabItem;
} }
return self; return self;
} }
@ -42,14 +44,18 @@ static id newTabTarget;
-(struct browser_window *)browser { -(struct browser_window *)browser {
return browser; return browser;
} }
-(id)tabItem {
return tabItem;
}
@end @end
@interface BrowserWindowController (Private) @interface BrowserWindowController (Private)
-(void)openUrlString: (NSString*)aUrlString; -(void)openUrlString: (NSString*)aUrlString;
-(void)addTab: (struct browser_window*)aBrowser; -(id)addTab: (struct browser_window*)aBrowser;
-(void)removeTab: (struct browser_window*)aBrowser; -(void)removeTab: (struct browser_window*)aBrowser;
-(void)reconfigureTabLayout; -(void)reconfigureTabLayout;
-(void)setActive: (TabContents*)tabContents; -(void)setActive: (TabContents*)tabContents;
-(Website*)currentWebsiteForTab: (id)tab;
@end @end
@implementation BrowserWindowController @implementation BrowserWindowController
@ -75,8 +81,8 @@ static id newTabTarget;
NSLog(@"Browser window loaded"); NSLog(@"Browser window loaded");
} }
-(void)newTabWithBrowser: (struct browser_window*)aBrowser { -(id)newTabWithBrowser: (struct browser_window*)aBrowser {
[self addTab: aBrowser]; return [self addTab: aBrowser];
} }
-(void)newTab: (id)sender { -(void)newTab: (id)sender {
@ -124,25 +130,30 @@ static id newTabTarget;
browser_window_destroy([tc browser]); browser_window_destroy([tc browser]);
} }
-(void)netsurfWindowDestroy { -(void)netsurfWindowDestroyForTab: (id)tab {
NSLog(@"ns destroy"); NSLog(@"ns destroy");
// If we're closing anyway, don't bother with tab cleanup. // If we're closing anyway, don't bother with tab cleanup.
if (isClosing) { if (isClosing) {
return; return;
} }
NSTabViewItem *selectedTab = [tabView selectedTabViewItem]; NSInteger idx = [tabView indexOfTabViewItem: [tab tabItem]];
NSInteger idx = [tabView indexOfTabViewItem: selectedTab];
if (idx == NSNotFound) { if (idx == NSNotFound) {
NSLog(@"Tab not found."); NSLog(@"Tab not found.");
return; return;
} }
[tabView removeTabViewItem: selectedTab]; [tabView removeTabViewItem: [tab tabItem]];
[tabs removeObjectAtIndex: idx]; [tabs removeObjectAtIndex: idx];
if ([tabs count] < 1) { if ([tabs count] < 1) {
[super close]; [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 { -(void)back: (id)sender {
NSLog(@"Browser backward"); NSLog(@"Browser backward");
[plotView back: sender]; [plotView back: sender];
@ -184,33 +195,33 @@ static id newTabTarget;
[self openUrlString: [aWebsite url]]; [self openUrlString: [aWebsite url]];
} }
-(NSSize)getBrowserSize { -(NSSize)getBrowserSizeForTab: (id)tab {
return [[plotView superview] frame].size; return [[[tab plotView] superview] frame].size;
} }
-(NSPoint)getBrowserScroll { -(NSPoint)getBrowserScrollForTab: (id)tab {
return [plotView visibleRect].origin; return [[tab plotView] visibleRect].origin;
} }
-(void)setBrowserScroll: (NSPoint)scroll { -(void)setBrowserScroll: (NSPoint)scroll forTab: (id)tab {
[plotView scrollPoint: scroll]; [[tab plotView] scrollPoint: scroll];
} }
-(void)invalidateBrowser { -(void)invalidateBrowserForTab: (id)tab {
[plotView setNeedsDisplay: YES]; [[tab plotView] setNeedsDisplay: YES];
} }
-(void)invalidateBrowser: (NSRect)rect { -(void)invalidateBrowser: (NSRect)rect forTab: (id)tab {
[plotView setNeedsDisplayInRect: rect]; [[tab plotView] setNeedsDisplayInRect: rect];
} }
-(void)updateBrowserExtent { -(void)updateBrowserExtentForTab: (id)tab {
int width, height; 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); 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); NSLog(@"Place caret... on %@", plotView);
[plotView placeCaretAtX: x y: y height: height]; [[tab plotView] placeCaretAtX: x y: y height: height];
} }
-(void)removeCaret { -(void)removeCaretInTab: (id)tab {
[plotView removeCaret]; [[tab plotView] removeCaret];
} }
-(void)setPointerToShape: (enum gui_pointer_shape)shape { -(void)setPointerToShape: (enum gui_pointer_shape)shape {
if (shape == lastRequestedPointer) if (shape == lastRequestedPointer)
@ -241,19 +252,10 @@ static id newTabTarget;
[[NSCursor arrowCursor] set]; [[NSCursor arrowCursor] set];
} }
} }
-(void)newContent { -(void)newContentForTab: (id)tab {
NSLog(@"New content"); NSLog(@"New content");
struct nsurl *url = browser_window_access_url(browser); Website *website = [self currentWebsiteForTab: activeTab];
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 addToHistory]; [website addToHistory];
[website release];
} }
-(void)startThrobber { -(void)startThrobber {
[refreshButton setTitle: @"Stop"]; [refreshButton setTitle: @"Stop"];
@ -263,17 +265,16 @@ static id newTabTarget;
[refreshButton setTitle: @"Refresh"]; [refreshButton setTitle: @"Refresh"];
[refreshButton setTag: 0]; [refreshButton setTag: 0];
} }
-(void)setNavigationUrl: (NSString*)urlString { -(void)setNavigationUrl: (NSString*)urlString forTab: (id)tab {
[urlBar setStringValue: urlString]; [urlBar setStringValue: urlString];
} }
-(void)setTitle: (NSString*)title { -(void)setTitle: (NSString*)title forTab: (id)tab {
[[self window] setTitle: title]; [[self window] setTitle: title];
NSTabViewItem *selectedTab = [tabView selectedTabViewItem];
NSString *tabTitle = title; NSString *tabTitle = title;
if ([tabTitle length] > TAB_TITLE_LEN) { if ([tabTitle length] > TAB_TITLE_LEN) {
tabTitle = [title substringToIndex: 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 { -(void)findNext: (NSString*)needle matchCase: (BOOL)matchCase sender: (id)sender {
@ -301,26 +302,15 @@ static id newTabTarget;
} }
-(void)bookmarkPage: (id)sender { -(void)bookmarkPage: (id)sender {
struct nsurl *url = browser_window_access_url(browser); Website *website = [self currentWebsiteForTab: activeTab];
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];
CreateBookmarkPanelController *bmController = [[CreateBookmarkPanelController alloc] CreateBookmarkPanelController *bmController = [[CreateBookmarkPanelController alloc]
initForWebsite: website]; initForWebsite: website];
[NSApp runModalForWindow: [bmController window]]; [NSApp runModalForWindow: [bmController window]];
[bmController release]; [bmController release];
[website release];
} }
-(NSString*)visibleUrl { -(NSString*)visibleUrl {
struct nsurl *url = browser_window_access_url(browser); return [[self currentWebsiteForTab: activeTab] url];
NSString *urlStr = [NSString stringWithCString: nsurl_access(url)];
return urlStr;
} }
-(void)openUrlString: (NSString*)aUrlString { -(void)openUrlString: (NSString*)aUrlString {
@ -354,7 +344,7 @@ static id newTabTarget;
[self setActive: tc]; [self setActive: tc];
} }
-(void)addTab: (struct browser_window*)aBrowser { -(id)addTab: (struct browser_window*)aBrowser {
NSString *identity = @"New Tab"; NSString *identity = @"New Tab";
NSTabViewItem *tabItem = [[NSTabViewItem alloc] initWithIdentifier: NSTabViewItem *tabItem = [[NSTabViewItem alloc] initWithIdentifier:
identity]; identity];
@ -376,7 +366,7 @@ static id newTabTarget;
[tabView insertTabViewItem: tabItem atIndex: num]; [tabView insertTabViewItem: tabItem atIndex: num];
TabContents *tc = [[TabContents alloc] initWithScroll: newScrollView plot: TabContents *tc = [[TabContents alloc] initWithScroll: newScrollView plot:
newPlotView browser: aBrowser]; newPlotView browser: aBrowser tabItem: tabItem];
[self setActive: tc]; [self setActive: tc];
[tabs addObject: tc]; [tabs addObject: tc];
[tabView selectTabViewItem: tabItem]; [tabView selectTabViewItem: tabItem];
@ -385,6 +375,7 @@ static id newTabTarget;
[tc release]; [tc release];
[newPlotView release]; [newPlotView release];
[newScrollView release]; [newScrollView release];
return tc;
} }
-(void)removeTab: (struct browser_window*)aBrowser { -(void)removeTab: (struct browser_window*)aBrowser {
@ -399,6 +390,20 @@ static id newTabTarget;
plotView = [tabContents plotView]; plotView = [tabContents plotView];
scrollView = [tabContents scrollView]; scrollView = [tabContents scrollView];
browser = [tabContents browser]; 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 { +(id)newTabTarget {

View File

@ -9,6 +9,11 @@
#import "utils/nsurl.h" #import "utils/nsurl.h"
#import "netsurf/mouse.h" #import "netsurf/mouse.h"
struct window_tab {
BrowserWindowController *window;
id tab;
};
/********************/ /********************/
/****** Window ******/ /****** Window ******/
/********************/ /********************/
@ -19,32 +24,40 @@ static struct gui_window *gnustep_window_create(struct browser_window *bw,
gui_window_create_flags flags) { gui_window_create_flags flags) {
NSLog(@"gnustep_window_create"); NSLog(@"gnustep_window_create");
BrowserWindowController *controller = nil; BrowserWindowController *controller = nil;
id tabId;
if (flags & BW_CREATE_TAB) { if (flags & BW_CREATE_TAB) {
controller = [BrowserWindowController newTabTarget]; controller = [BrowserWindowController newTabTarget];
[controller newTabWithBrowser: bw]; tabId = [controller newTabWithBrowser: bw];
} }
if (controller == nil) { if (controller == nil) {
controller = [[BrowserWindowController alloc] controller = [[BrowserWindowController alloc]
initWithBrowser: bw]; initWithBrowser: bw];
[controller loadWindow]; [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 // Destroy the specified window
static void gnustep_window_destroy(struct gui_window *gw) { static void gnustep_window_destroy(struct gui_window *gw) {
NSLog(@"gnustep_window_destroy"); 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 // 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) { static nserror gnustep_window_invalidate(struct gui_window *gw, const struct rect *rect) {
NSLog(@"gnustep_window_invalidate"); NSLog(@"gnustep_window_invalidate");
struct window_tab *wtab = (struct window_tab*)gw;
if (rect == NULL) { if (rect == NULL) {
[(id)gw invalidateBrowser]; [wtab->window invalidateBrowserForTab: wtab->tab];
} else { } else {
[(id)gw invalidateBrowser: NSMakeRect(rect->x0, rect->y0, [wtab->window invalidateBrowser: NSMakeRect(rect->x0, rect->y0,
rect->x1, rect->y1)]; rect->x1, rect->y1) forTab: wtab->tab];
} }
return NSERROR_OK; 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 // Put the current scroll offset into sx and sy
static bool gnustep_window_get_scroll(struct gui_window *gw, int *sx, int *sy) { static bool gnustep_window_get_scroll(struct gui_window *gw, int *sx, int *sy) {
NSLog(@"gnustep_window_get_scroll"); 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; *sx = scroll.x;
*sy = scroll.y; *sy = scroll.y;
return true; 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 // Set the current scroll offset
static nserror gnustep_window_set_scroll(struct gui_window *gw, const struct rect *rect) { static nserror gnustep_window_set_scroll(struct gui_window *gw, const struct rect *rect) {
NSLog(@"gnustep_window_set_scroll"); 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; return NSERROR_OK;
} }
// Put the dimensions of the specified window into width, height // Put the dimensions of the specified window into width, height
static nserror gnustep_window_get_dimensions(struct gui_window *gw, int *width, int *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; *width = size.width;
*height = size.height; *height = size.height;
NSLog(@"gnustep_window_get_dimensions (%d, %d)", *width, *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 // Some kind of event happened
static nserror gnustep_window_event(struct gui_window *gw, enum gui_window_event event) { static nserror gnustep_window_event(struct gui_window *gw, enum gui_window_event event) {
NSLog(@"gnustep_window_event"); NSLog(@"gnustep_window_event");
struct window_tab *wtab = (struct window_tab*)gw;
switch (event) { switch (event) {
case GW_EVENT_UPDATE_EXTENT: case GW_EVENT_UPDATE_EXTENT:
NSLog(@"GW_EVENT_UPDATE_EXTENT"); NSLog(@"GW_EVENT_UPDATE_EXTENT");
[(id)gw updateBrowserExtent]; [wtab->window updateBrowserExtentForTab: wtab->tab];
break; break;
case GW_EVENT_REMOVE_CARET: case GW_EVENT_REMOVE_CARET:
NSLog(@"GW_EVENT_REMOVE_CARET"); NSLog(@"GW_EVENT_REMOVE_CARET");
[(id)gw removeCaret]; [wtab->window removeCaretInTab: wtab->tab];
break; break;
case GW_EVENT_NEW_CONTENT: case GW_EVENT_NEW_CONTENT:
NSLog(@"GW_EVENT_NEW_CONTENT"); NSLog(@"GW_EVENT_NEW_CONTENT");
[(id)gw newContent]; [wtab->window newContentForTab: wtab->tab];
break; break;
case GW_EVENT_START_THROBBER: case GW_EVENT_START_THROBBER:
NSLog(@"GW_EVENT_START_THROBBER"); NSLog(@"GW_EVENT_START_THROBBER");
[(id)gw startThrobber]; [wtab->window startThrobber];
break; break;
case GW_EVENT_STOP_THROBBER: case GW_EVENT_STOP_THROBBER:
NSLog(@"GW_EVENT_STOP_THROBBER"); NSLog(@"GW_EVENT_STOP_THROBBER");
[(id)gw stopThrobber]; [wtab->window stopThrobber];
break; break;
default: default:
NSLog(@"Unknown window event."); 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) { 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) { 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)]; NSString *urlStr = [NSString stringWithUTF8String: nsurl_access(url)];
[(id)gw setNavigationUrl: urlStr]; [wtab->window setNavigationUrl: urlStr forTab: wtab->tab];
return NSERROR_OK; return NSERROR_OK;
} }
static void gnustep_window_set_pointer(struct gui_window *gw, enum gui_pointer_shape shape) { 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) { 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 = { struct gui_window_table gnustep_window_table = {