1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-03-15 16:29:34 +00:00

macOS revert fullscreen changes (#3304)

* macOS remove NSWindow subclass

as discussed in #3297
This commit is contained in:
SweetPPro 2022-06-16 19:55:33 +02:00 committed by GitHub
parent 037f1bf403
commit c6b49e99d8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 443 additions and 409 deletions

View file

@ -21,7 +21,6 @@
3C7A11980D0B2EE300B5701F /* getgateway.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C7A11920D0B2EE300B5701F /* getgateway.h */; };
3C7A11990D0B2EE300B5701F /* natpmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C7A11930D0B2EE300B5701F /* natpmp.c */; };
3C7A119A0D0B2EE300B5701F /* natpmp.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C7A11940D0B2EE300B5701F /* natpmp.h */; };
456B90D02855332F000D4D80 /* ControllerWindowMethods.mm in Sources */ = {isa = PBXBuildFile; fileRef = 456B90CE2855332F000D4D80 /* ControllerWindowMethods.mm */; };
45A7D3292843B54D00F0C32A /* GroupPopUpButtonCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = 45A7D3282843B54D00F0C32A /* GroupPopUpButtonCell.mm */; };
45A7D32C2843B55F00F0C32A /* PriorityPopUpButtonCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = 45A7D32B2843B55F00F0C32A /* PriorityPopUpButtonCell.mm */; };
4D043A7F090AE979009FEDA8 /* TransmissionDocument.icns in Resources */ = {isa = PBXBuildFile; fileRef = 4D043A7E090AE979009FEDA8 /* TransmissionDocument.icns */; };
@ -614,8 +613,6 @@
3C7A11920D0B2EE300B5701F /* getgateway.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = getgateway.h; sourceTree = "<group>"; };
3C7A11930D0B2EE300B5701F /* natpmp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = natpmp.c; sourceTree = "<group>"; };
3C7A11940D0B2EE300B5701F /* natpmp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = natpmp.h; sourceTree = "<group>"; };
456B90CE2855332F000D4D80 /* ControllerWindowMethods.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ControllerWindowMethods.mm; sourceTree = "<group>"; };
456B90CF2855332F000D4D80 /* ControllerWindowMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ControllerWindowMethods.h; sourceTree = "<group>"; };
45A7D3272843B54D00F0C32A /* GroupPopUpButtonCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GroupPopUpButtonCell.h; sourceTree = "<group>"; };
45A7D3282843B54D00F0C32A /* GroupPopUpButtonCell.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GroupPopUpButtonCell.mm; sourceTree = "<group>"; };
45A7D32A2843B55F00F0C32A /* PriorityPopUpButtonCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PriorityPopUpButtonCell.h; sourceTree = "<group>"; };
@ -1391,8 +1388,6 @@
C86BCD9828228A9600F45599 /* SparkleProxy.mm */,
4DF0C5AA0899190500DD8943 /* Controller.h */,
4DF0C5A90899190500DD8943 /* Controller.mm */,
456B90CF2855332F000D4D80 /* ControllerWindowMethods.h */,
456B90CE2855332F000D4D80 /* ControllerWindowMethods.mm */,
4DFBC2DD09C0970D00D5C571 /* Torrent.h */,
4DFBC2DE09C0970D00D5C571 /* Torrent.mm */,
A27F0F310E19AD9800B2DB97 /* TorrentGroup.h */,
@ -3028,7 +3023,6 @@
35F373030C2DA89000DAA8F2 /* FilePriorityCell.mm in Sources */,
A2085DDC0C53BC74000BC3B7 /* AboutWindowController.mm in Sources */,
A21282A80CA6C66800EAEE0F /* StatusBarView.mm in Sources */,
456B90D02855332F000D4D80 /* ControllerWindowMethods.mm in Sources */,
A257C1820CAD3003004E121C /* PeerTableView.mm in Sources */,
A2A6321B0CD9751700E3DA60 /* BadgeView.mm in Sources */,
A2ED7D8F0CEF431B00970975 /* FilterButton.mm in Sources */,

View file

@ -74,8 +74,8 @@
self.fNameField.stringValue = name;
self.fNameField.toolTip = name;
//make window an auxillary view in fullscreen
[self.window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
//disable fullscreen support
[self.window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenNone];
[self setGroupsMenu];
[self.fGroupPopUp selectItemWithTag:self.fGroupValue];

View file

@ -106,8 +106,8 @@
self.fNameField.stringValue = name;
self.fNameField.toolTip = name;
//make window an auxillary view in fullscreen
[self.window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
//disable fullscreen support
[self.window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenNone];
self.fIconView.image = self.torrent.icon;

View file

@ -50,7 +50,6 @@ set(${PROJECT_NAME}_SOURCES
ButtonToolbarItem.mm
ColorTextField.mm
Controller.mm
ControllerWindowMethods.mm
CreatorWindowController.mm
DragOverlayView.mm
DragOverlayWindow.mm

View file

@ -10,7 +10,6 @@
#include <libtransmission/transmission.h>
#import "VDKQueue.h"
#import "TorrentTableView.h"
@class AddMagnetWindowController;
@class AddWindowController;
@ -159,12 +158,20 @@ typedef NS_ENUM(unsigned int, addType) { //
- (void)toggleAvailabilityBar:(id)sender;
- (void)toggleStatusBar:(id)sender;
- (void)showStatusBar:(BOOL)show animate:(BOOL)animate;
- (void)toggleFilterBar:(id)sender;
- (void)showFilterBar:(BOOL)show animate:(BOOL)animate;
- (void)focusFilterField;
- (void)allToolbarClicked:(id)sender;
- (void)selectedToolbarClicked:(id)sender;
- (void)setWindowSizeToFit;
@property(nonatomic, readonly) NSRect sizedWindowFrame;
- (void)updateForAutoSize;
- (void)setWindowMinMaxToCurrent;
@property(nonatomic, readonly) CGFloat minWindowContentSizeAllowed;
- (void)updateForExpandCollapse;
- (void)showMainWindow:(id)sender;
@ -184,71 +191,4 @@ typedef NS_ENUM(unsigned int, addType) { //
- (void)rpcMovedTorrent:(Torrent*)torrent;
- (void)rpcUpdateQueue;
@property(nonatomic) IBOutlet NSWindow* fWindow;
@property(nonatomic) IBOutlet TorrentTableView* fTableView;
@property(nonatomic) IBOutlet NSMenuItem* fOpenIgnoreDownloadFolder;
@property(nonatomic) IBOutlet NSButton* fActionButton;
@property(nonatomic) IBOutlet NSButton* fSpeedLimitButton;
@property(nonatomic) IBOutlet NSButton* fClearCompletedButton;
@property(nonatomic) IBOutlet NSTextField* fTotalTorrentsField;
@property(nonatomic) IBOutlet NSMenuItem* fNextFilterItem;
@property(nonatomic) IBOutlet NSMenuItem* fNextInfoTabItem;
@property(nonatomic) IBOutlet NSMenuItem* fPrevInfoTabItem;
@property(nonatomic) IBOutlet NSMenu* fSortMenu;
@property(nonatomic) IBOutlet NSMenu* fGroupsSetMenu;
@property(nonatomic) IBOutlet NSMenu* fGroupsSetContextMenu;
@property(nonatomic) IBOutlet NSMenu* fShareMenu;
@property(nonatomic) IBOutlet NSMenu* fShareContextMenu;
@property(nonatomic) IBOutlet NSMenuItem* fShareMenuItem; // remove when dropping 10.6
@property(nonatomic) IBOutlet NSMenuItem* fShareContextMenuItem; // remove when dropping 10.6
@property(nonatomic, readonly) tr_session* fLib;
@property(nonatomic, readonly) NSMutableArray<Torrent*>* fTorrents;
@property(nonatomic, readonly) NSMutableArray* fDisplayedTorrents;
@property(nonatomic, readonly) NSMutableDictionary<NSString*, Torrent*>* fTorrentHashes;
@property(nonatomic, readonly) InfoWindowController* fInfoController;
@property(nonatomic) MessageWindowController* fMessageController;
@property(nonatomic, readonly) NSUserDefaults* fDefaults;
@property(nonatomic, readonly) NSString* fConfigDirectory;
@property(nonatomic) DragOverlayWindow* fOverlayWindow;
@property(nonatomic) io_connect_t fRootPort;
@property(nonatomic) NSTimer* fTimer;
@property(nonatomic) StatusBarController* fStatusBar;
@property(nonatomic) FilterBarController* fFilterBar;
@property(nonatomic) QLPreviewPanel* fPreviewPanel;
@property(nonatomic) BOOL fQuitting;
@property(nonatomic) BOOL fQuitRequested;
@property(nonatomic, readonly) BOOL fPauseOnLaunch;
@property(nonatomic) Badger* fBadger;
@property(nonatomic) NSMutableArray<NSString*>* fAutoImportedNames;
@property(nonatomic) NSTimer* fAutoImportTimer;
@property(nonatomic) NSMutableDictionary<NSURL*, id>* fPendingTorrentDownloads;
@property(nonatomic) NSMutableSet<Torrent*>* fAddingTransfers;
@property(nonatomic) NSMutableSet<NSWindowController*>* fAddWindows;
@property(nonatomic) URLSheetWindowController* fUrlSheetController;
@property(nonatomic) BOOL fGlobalPopoverShown;
@property(nonatomic) NSView* fPositioningView;
@property(nonatomic) BOOL fSoundPlaying;
@property(nonatomic) id fNoNapActivity;
@end

View file

@ -22,9 +22,9 @@
#import "CocoaCompatibility.h"
#import "Controller.h"
#import "ControllerWindowMethods.h"
#import "Torrent.h"
#import "TorrentGroup.h"
#import "TorrentTableView.h"
#import "CreatorWindowController.h"
#import "StatsWindowController.h"
#import "InfoWindowController.h"
@ -42,6 +42,8 @@
#import "ShareTorrentFileHelper.h"
#import "ToolbarSegmentedCell.h"
#import "BlocklistDownloader.h"
#import "StatusBarController.h"
#import "FilterBarController.h"
#import "FileRenameSheetController.h"
#import "BonjourController.h"
#import "Badger.h"
@ -101,6 +103,10 @@ typedef NS_ENUM(unsigned int, sortOrderTag) { //
#define ROW_HEIGHT_REGULAR 62.0
#define ROW_HEIGHT_SMALL 22.0
#define WINDOW_REGULAR_WIDTH 468.0
#define STATUS_BAR_HEIGHT 21.0
#define FILTER_BAR_HEIGHT 23.0
#define UPDATE_UI_SECONDS 1.0
@ -221,6 +227,77 @@ static void removeKeRangerRansomware()
NSLog(@"OSX.KeRanger.A ransomware removal completed, proceeding to normal operation");
}
@interface Controller ()
@property(nonatomic) IBOutlet NSWindow* fWindow;
@property(nonatomic) IBOutlet TorrentTableView* fTableView;
@property(nonatomic) IBOutlet NSMenuItem* fOpenIgnoreDownloadFolder;
@property(nonatomic) IBOutlet NSButton* fActionButton;
@property(nonatomic) IBOutlet NSButton* fSpeedLimitButton;
@property(nonatomic) IBOutlet NSButton* fClearCompletedButton;
@property(nonatomic) IBOutlet NSTextField* fTotalTorrentsField;
@property(nonatomic) IBOutlet NSMenuItem* fNextFilterItem;
@property(nonatomic) IBOutlet NSMenuItem* fNextInfoTabItem;
@property(nonatomic) IBOutlet NSMenuItem* fPrevInfoTabItem;
@property(nonatomic) IBOutlet NSMenu* fSortMenu;
@property(nonatomic) IBOutlet NSMenu* fGroupsSetMenu;
@property(nonatomic) IBOutlet NSMenu* fGroupsSetContextMenu;
@property(nonatomic) IBOutlet NSMenu* fShareMenu;
@property(nonatomic) IBOutlet NSMenu* fShareContextMenu;
@property(nonatomic) IBOutlet NSMenuItem* fShareMenuItem; // remove when dropping 10.6
@property(nonatomic) IBOutlet NSMenuItem* fShareContextMenuItem; // remove when dropping 10.6
@property(nonatomic, readonly) tr_session* fLib;
@property(nonatomic, readonly) NSMutableArray<Torrent*>* fTorrents;
@property(nonatomic, readonly) NSMutableArray* fDisplayedTorrents;
@property(nonatomic, readonly) NSMutableDictionary<NSString*, Torrent*>* fTorrentHashes;
@property(nonatomic, readonly) InfoWindowController* fInfoController;
@property(nonatomic) MessageWindowController* fMessageController;
@property(nonatomic, readonly) NSUserDefaults* fDefaults;
@property(nonatomic, readonly) NSString* fConfigDirectory;
@property(nonatomic) DragOverlayWindow* fOverlayWindow;
@property(nonatomic) io_connect_t fRootPort;
@property(nonatomic) NSTimer* fTimer;
@property(nonatomic) StatusBarController* fStatusBar;
@property(nonatomic) FilterBarController* fFilterBar;
@property(nonatomic) QLPreviewPanel* fPreviewPanel;
@property(nonatomic) BOOL fQuitting;
@property(nonatomic) BOOL fQuitRequested;
@property(nonatomic, readonly) BOOL fPauseOnLaunch;
@property(nonatomic) Badger* fBadger;
@property(nonatomic) NSMutableArray<NSString*>* fAutoImportedNames;
@property(nonatomic) NSTimer* fAutoImportTimer;
@property(nonatomic) NSMutableDictionary<NSURL*, id>* fPendingTorrentDownloads;
@property(nonatomic) NSMutableSet<Torrent*>* fAddingTransfers;
@property(nonatomic) NSMutableSet<NSWindowController*>* fAddWindows;
@property(nonatomic) URLSheetWindowController* fUrlSheetController;
@property(nonatomic) BOOL fGlobalPopoverShown;
@property(nonatomic) NSView* fPositioningView;
@property(nonatomic) BOOL fSoundPlaying;
@property(nonatomic) id fNoNapActivity;
@end
@implementation Controller
+ (void)initialize
@ -485,12 +562,12 @@ static void removeKeRangerRansomware()
self.fWindow.delegate = self; //do manually to avoid placement issue
//disable fullscreen support
[self.fWindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenNone];
[self.fWindow makeFirstResponder:self.fTableView];
self.fWindow.excludedFromWindowsMenu = YES;
//make window primary view in fullscreen
[self.fWindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
//set table size
BOOL const small = [self.fDefaults boolForKey:@"SmallView"];
if (small)
@ -504,6 +581,12 @@ static void removeKeRangerRansomware()
self.fTotalTorrentsField.cell.backgroundStyle = NSBackgroundStyleRaised;
//set up filter bar
[self showFilterBar:[self.fDefaults boolForKey:@"FilterBar"] animate:NO];
//set up status bar
[self showStatusBar:[self.fDefaults boolForKey:@"StatusBar"] animate:NO];
self.fActionButton.toolTip = NSLocalizedString(@"Shortcuts for changing global settings.", "Main window -> 1st bottom left button (action) tooltip");
self.fSpeedLimitButton.toolTip = NSLocalizedString(
@"Speed Limit overrides the total bandwidth limits with its own limits.",
@ -547,6 +630,13 @@ static void removeKeRangerRansomware()
[self.fSortMenu insertItem:item atIndex:sortMenuIndex++];
}
//you would think this would be called later in this method from updateUI, but it's not reached in awakeFromNib
//this must be called after showStatusBar:
[self.fStatusBar updateWithDownload:0.0 upload:0.0];
//this should also be after the rest of the setup
[self updateForAutoSize];
//register for sleep notifications
IONotificationPortRef notify;
io_object_t iterator;
@ -658,7 +748,7 @@ static void removeKeRangerRansomware()
#warning rename
[nc addObserver:self selector:@selector(fullUpdateUI) name:@"UpdateQueue" object:nil];
[nc addObserver:self selector:@selector(drawMainWindow) name:@"ApplyFilter" object:nil];
[nc addObserver:self selector:@selector(applyFilter) name:@"ApplyFilter" object:nil];
//open newly created torrent file
[nc addObserver:self selector:@selector(beginCreateFile:) name:@"BeginCreateTorrentFile" object:nil];
@ -668,8 +758,6 @@ static void removeKeRangerRansomware()
[nc addObserver:self selector:@selector(applyFilter) name:@"UpdateGroups" object:nil];
[self drawMainWindow];
//timer to update the interface every second
[self updateUI];
self.fTimer = [NSTimer scheduledTimerWithTimeInterval:UPDATE_UI_SECONDS target:self selector:@selector(updateUI)
@ -678,6 +766,8 @@ static void removeKeRangerRansomware()
[NSRunLoop.currentRunLoop addTimer:self.fTimer forMode:NSModalPanelRunLoopMode];
[NSRunLoop.currentRunLoop addTimer:self.fTimer forMode:NSEventTrackingRunLoopMode];
[self applyFilter];
[self.fWindow makeKeyAndOrderFront:nil];
if ([self.fDefaults boolForKey:@"InfoVisible"])
@ -879,6 +969,9 @@ static void removeKeRangerRansomware()
[window close];
}
[self showStatusBar:NO animate:NO];
[self showFilterBar:NO animate:NO];
//save history
[self updateTorrentHistory];
[self.fTableView saveCollapsedGroups];
@ -1114,7 +1207,7 @@ static void removeKeRangerRansomware()
}
}
[self drawMainWindow];
[self fullUpdateUI];
}
- (void)askOpenConfirmed:(AddWindowController*)addController add:(BOOL)add
@ -1134,7 +1227,7 @@ static void removeKeRangerRansomware()
}
[self.fAddingTransfers addObject:torrent];
[self drawMainWindow];
[self fullUpdateUI];
}
else
{
@ -1208,7 +1301,7 @@ static void removeKeRangerRansomware()
[self.fAddingTransfers addObject:torrent];
}
[self drawMainWindow];
[self fullUpdateUI];
}
- (void)askOpenMagnetConfirmed:(AddMagnetWindowController*)addController add:(BOOL)add
@ -1228,7 +1321,7 @@ static void removeKeRangerRansomware()
}
[self.fAddingTransfers addObject:torrent];
[self drawMainWindow];
[self fullUpdateUI];
}
else
{
@ -1725,8 +1818,6 @@ static void removeKeRangerRansomware()
{
[torrent closeRemoveTorrent:deleteData];
}
[self drawMainWindow];
};
[self.fTableView beginUpdates];
@ -1768,9 +1859,9 @@ static void removeKeRangerRansomware()
{
[torrent closeRemoveTorrent:deleteData];
}
[self drawMainWindow];
}
[self fullUpdateUI];
}
- (void)removeNoDelete:(id)sender
@ -3728,7 +3819,7 @@ static void removeKeRangerRansomware()
[self.fTableView endUpdates];
//resize for larger min height if not set to auto size
if (![self.fDefaults boolForKey:@"AutoSize"] || self.isFullScreen)
if (![self.fDefaults boolForKey:@"AutoSize"])
{
NSSize const contentSize = self.fWindow.contentView.frame.size;
@ -3751,8 +3842,6 @@ static void removeKeRangerRansomware()
{
[self setWindowSizeToFit];
}
[self drawMainWindow];
}
- (void)togglePiecesBar:(id)sender
@ -3767,29 +3856,266 @@ static void removeKeRangerRansomware()
[self.fTableView display];
}
- (NSRect)windowFrameByAddingHeight:(CGFloat)height checkLimits:(BOOL)check
{
NSScrollView* scrollView = self.fTableView.enclosingScrollView;
//convert pixels to points
NSRect windowFrame = self.fWindow.frame;
NSSize windowSize = [scrollView convertSize:windowFrame.size fromView:nil];
windowSize.height += height;
if (check)
{
//we can't call minSize, since it might be set to the current size (auto size)
CGFloat const minHeight = self.minWindowContentSizeAllowed +
(NSHeight(self.fWindow.frame) - NSHeight(self.fWindow.contentView.frame)); //contentView to window
if (windowSize.height <= minHeight)
{
windowSize.height = minHeight;
}
else
{
NSScreen* screen = self.fWindow.screen;
if (screen)
{
NSSize maxSize = [scrollView convertSize:screen.visibleFrame.size fromView:nil];
if (!self.fStatusBar)
{
maxSize.height -= STATUS_BAR_HEIGHT;
}
if (!self.fFilterBar)
{
maxSize.height -= FILTER_BAR_HEIGHT;
}
if (windowSize.height > maxSize.height)
{
windowSize.height = maxSize.height;
}
}
}
}
//convert points to pixels
windowSize = [scrollView convertSize:windowSize toView:nil];
windowFrame.origin.y -= (windowSize.height - windowFrame.size.height);
windowFrame.size.height = windowSize.height;
return windowFrame;
}
- (void)toggleStatusBar:(id)sender
{
BOOL const show = self.fStatusBar == nil;
[self showStatusBar:show animate:YES];
[self.fDefaults setBool:show forKey:@"StatusBar"];
[self drawMainWindow];
}
//doesn't save shown state
- (void)showStatusBar:(BOOL)show animate:(BOOL)animate
{
BOOL const prevShown = self.fStatusBar != nil;
if (show == prevShown)
{
return;
}
if (show)
{
self.fStatusBar = [[StatusBarController alloc] initWithLib:self.fLib];
NSView* contentView = self.fWindow.contentView;
NSSize const windowSize = [contentView convertSize:self.fWindow.frame.size fromView:nil];
NSRect statusBarFrame = self.fStatusBar.view.frame;
statusBarFrame.size.width = windowSize.width;
self.fStatusBar.view.frame = statusBarFrame;
[contentView addSubview:self.fStatusBar.view];
[self.fStatusBar.view setFrameOrigin:NSMakePoint(0.0, NSMaxY(contentView.frame))];
}
CGFloat heightChange = self.fStatusBar.view.frame.size.height;
if (!show)
{
heightChange *= -1;
}
//allow bar to show even if not enough room
if (show && ![self.fDefaults boolForKey:@"AutoSize"])
{
NSRect frame = [self windowFrameByAddingHeight:heightChange checkLimits:NO];
NSScreen* screen = self.fWindow.screen;
if (screen)
{
CGFloat change = screen.visibleFrame.size.height - frame.size.height;
if (change < 0.0)
{
frame = self.fWindow.frame;
frame.size.height += change;
frame.origin.y -= change;
[self.fWindow setFrame:frame display:NO animate:NO];
}
}
}
[self updateUI];
NSScrollView* scrollView = self.fTableView.enclosingScrollView;
//set views to not autoresize
NSUInteger const statsMask = self.fStatusBar.view.autoresizingMask;
self.fStatusBar.view.autoresizingMask = NSViewNotSizable;
NSUInteger filterMask;
if (self.fFilterBar)
{
filterMask = self.fFilterBar.view.autoresizingMask;
self.fFilterBar.view.autoresizingMask = NSViewNotSizable;
}
NSUInteger const scrollMask = scrollView.autoresizingMask;
scrollView.autoresizingMask = NSViewNotSizable;
NSRect const frame = [self windowFrameByAddingHeight:heightChange checkLimits:NO];
[self.fWindow setFrame:frame display:YES animate:animate];
//re-enable autoresize
self.fStatusBar.view.autoresizingMask = statsMask;
if (self.fFilterBar)
{
self.fFilterBar.view.autoresizingMask = filterMask;
}
scrollView.autoresizingMask = scrollMask;
if (!show)
{
[self.fStatusBar.view removeFromSuperviewWithoutNeedingDisplay];
self.fStatusBar = nil;
}
if ([self.fDefaults boolForKey:@"AutoSize"])
{
[self setWindowMinMaxToCurrent];
}
else
{
//change min size
NSSize minSize = self.fWindow.contentMinSize;
minSize.height += heightChange;
self.fWindow.contentMinSize = minSize;
}
}
- (void)toggleFilterBar:(id)sender
{
BOOL const show = self.fFilterBar == nil;
//disable filtering when hiding (have to do before drawMainWindow:)
//disable filtering when hiding (have to do before showFilterBar:animate:)
if (!show)
{
[self.fFilterBar reset:NO];
}
[self showFilterBar:show animate:YES];
[self.fDefaults setBool:show forKey:@"FilterBar"];
[self drawMainWindow];
[self.fWindow.toolbar validateVisibleItems];
[self applyFilter]; //do even if showing to ensure tooltips are updated
}
//doesn't save shown state
- (void)showFilterBar:(BOOL)show animate:(BOOL)animate
{
BOOL const prevShown = self.fFilterBar != nil;
if (show == prevShown)
{
return;
}
if (show)
{
[self focusFilterField];
self.fFilterBar = [[FilterBarController alloc] init];
NSView* contentView = self.fWindow.contentView;
NSSize const windowSize = [contentView convertSize:self.fWindow.frame.size fromView:nil];
NSRect filterBarFrame = self.fFilterBar.view.frame;
filterBarFrame.size.width = windowSize.width;
self.fFilterBar.view.frame = filterBarFrame;
if (self.fStatusBar)
{
[contentView addSubview:self.fFilterBar.view positioned:NSWindowBelow relativeTo:self.fStatusBar.view];
}
else
{
[contentView addSubview:self.fFilterBar.view];
}
CGFloat const originY = self.fStatusBar ? NSMinY(self.fStatusBar.view.frame) : NSMaxY(contentView.frame);
[self.fFilterBar.view setFrameOrigin:NSMakePoint(0.0, originY)];
}
else
{
[self.fWindow makeFirstResponder:self.fTableView];
}
CGFloat heightChange = NSHeight(self.fFilterBar.view.frame);
if (!show)
{
heightChange *= -1;
}
//allow bar to show even if not enough room
if (show && ![self.fDefaults boolForKey:@"AutoSize"])
{
NSRect frame = [self windowFrameByAddingHeight:heightChange checkLimits:NO];
NSScreen* screen = self.fWindow.screen;
if (screen)
{
CGFloat change = screen.visibleFrame.size.height - frame.size.height;
if (change < 0.0)
{
frame = self.fWindow.frame;
frame.size.height += change;
frame.origin.y -= change;
[self.fWindow setFrame:frame display:NO animate:NO];
}
}
}
NSScrollView* scrollView = self.fTableView.enclosingScrollView;
//set views to not autoresize
NSUInteger const filterMask = self.fFilterBar.view.autoresizingMask;
NSUInteger const scrollMask = scrollView.autoresizingMask;
self.fFilterBar.view.autoresizingMask = NSViewNotSizable;
scrollView.autoresizingMask = NSViewNotSizable;
NSRect const frame = [self windowFrameByAddingHeight:heightChange checkLimits:NO];
[self.fWindow setFrame:frame display:YES animate:animate];
//re-enable autoresize
self.fFilterBar.view.autoresizingMask = filterMask;
scrollView.autoresizingMask = scrollMask;
if (!show)
{
[self.fFilterBar.view removeFromSuperviewWithoutNeedingDisplay];
self.fFilterBar = nil;
}
if ([self.fDefaults boolForKey:@"AutoSize"])
{
[self setWindowMinMaxToCurrent];
}
else
{
//change min size
NSSize minSize = self.fWindow.contentMinSize;
minSize.height += heightChange;
self.fWindow.contentMinSize = minSize;
}
}
@ -4850,6 +5176,80 @@ static void removeKeRangerRansomware()
return menu;
}
- (NSRect)windowWillUseStandardFrame:(NSWindow*)window defaultFrame:(NSRect)defaultFrame
{
//if auto size is enabled, the current frame shouldn't need to change
NSRect frame = [self.fDefaults boolForKey:@"AutoSize"] ? window.frame : self.sizedWindowFrame;
frame.size.width = [self.fDefaults boolForKey:@"SmallView"] ? self.fWindow.minSize.width : WINDOW_REGULAR_WIDTH;
return frame;
}
- (void)setWindowSizeToFit
{
if ([self.fDefaults boolForKey:@"AutoSize"])
{
NSScrollView* scrollView = self.fTableView.enclosingScrollView;
scrollView.hasVerticalScroller = NO;
[self.fWindow setFrame:self.sizedWindowFrame display:YES animate:YES];
scrollView.hasVerticalScroller = YES;
[self setWindowMinMaxToCurrent];
}
}
- (NSRect)sizedWindowFrame
{
NSUInteger groups = (self.fDisplayedTorrents.count > 0 && ![self.fDisplayedTorrents[0] isKindOfClass:[Torrent class]]) ?
self.fDisplayedTorrents.count :
0;
CGFloat heightChange = (GROUP_SEPARATOR_HEIGHT + self.fTableView.intercellSpacing.height) * groups +
(self.fTableView.rowHeight + self.fTableView.intercellSpacing.height) * (self.fTableView.numberOfRows - groups) -
NSHeight(self.fTableView.enclosingScrollView.frame);
return [self windowFrameByAddingHeight:heightChange checkLimits:YES];
}
- (void)updateForAutoSize
{
if ([self.fDefaults boolForKey:@"AutoSize"])
{
[self setWindowSizeToFit];
}
else
{
NSSize contentMinSize = self.fWindow.contentMinSize;
contentMinSize.height = self.minWindowContentSizeAllowed;
self.fWindow.contentMinSize = contentMinSize;
NSSize contentMaxSize = self.fWindow.contentMaxSize;
contentMaxSize.height = FLT_MAX;
self.fWindow.contentMaxSize = contentMaxSize;
}
}
- (void)setWindowMinMaxToCurrent
{
CGFloat const height = NSHeight(self.fWindow.contentView.frame);
NSSize minSize = self.fWindow.contentMinSize, maxSize = self.fWindow.contentMaxSize;
minSize.height = height;
maxSize.height = height;
self.fWindow.contentMinSize = minSize;
self.fWindow.contentMaxSize = maxSize;
}
- (CGFloat)minWindowContentSizeAllowed
{
CGFloat contentMinHeight = NSHeight(self.fWindow.contentView.frame) - NSHeight(self.fTableView.enclosingScrollView.frame) +
self.fTableView.rowHeight + self.fTableView.intercellSpacing.height;
return contentMinHeight;
}
- (void)updateForExpandCollapse
{
[self setWindowSizeToFit];
@ -5007,7 +5407,7 @@ static void removeKeRangerRansomware()
}
[self.fAddingTransfers addObject:torrent];
[self drawMainWindow];
[self fullUpdateUI];
}
- (void)rpcRemoveTorrent:(Torrent*)torrent deleteData:(BOOL)deleteData

View file

@ -1,26 +0,0 @@
// This file Copyright © 2005-2022 Transmission authors and contributors.
// It may be used under the MIT (SPDX: MIT) license.
// License text can be found in the licenses/ folder.
#import "Controller.h"
#import "StatusBarController.h"
#import "FilterBarController.h"
#import "Torrent.h"
@interface Controller (ControllerWindowMethods)
- (void)drawMainWindow;
- (void)setWindowSizeToFit;
- (void)updateForAutoSize;
- (void)setWindowMinMaxToCurrent;
@property(nonatomic, readonly) NSRect sizedWindowFrame;
@property(nonatomic, readonly) CGFloat titlebarHeight;
@property(nonatomic, readonly) CGFloat mainWindowComponentHeight;
@property(nonatomic, readonly) CGFloat scrollViewHeight;
@property(nonatomic, readonly) CGFloat fullScreenScrollViewHeight;
@property(nonatomic, readonly) CGFloat minWindowContentSizeAllowed;
@property(nonatomic, readonly) BOOL isFullScreen;
@end

View file

@ -1,273 +0,0 @@
// This file Copyright © 2005-2022 Transmission authors and contributors.
// It may be used under the MIT (SPDX: MIT) license.
// License text can be found in the licenses/ folder.
#import "ControllerWindowMethods.h"
#define WINDOW_REGULAR_WIDTH 468.0
#define STATUS_BAR_HEIGHT 21.0
#define FILTER_BAR_HEIGHT 23.0
#define BOTTOM_BAR_HEIGHT 24.0
@implementation Controller (ControllerWindowMethods)
- (void)drawMainWindow
{
dispatch_async(dispatch_get_main_queue(), ^{
NSView* contentView = self.fWindow.contentView;
NSSize const windowSize = [contentView convertSize:self.fWindow.frame.size fromView:nil];
CGFloat originY = NSMaxY(contentView.frame);
//remove all subviews
for (id view in contentView.subviews.copy)
{
[view removeFromSuperviewWithoutNeedingDisplay];
}
self.fStatusBar = nil;
self.fFilterBar = nil;
if ([self.fDefaults boolForKey:@"StatusBar"])
{
self.fStatusBar = [[StatusBarController alloc] initWithLib:self.fLib];
NSRect statusBarFrame = self.fStatusBar.view.frame;
statusBarFrame.size.width = windowSize.width;
originY -= STATUS_BAR_HEIGHT;
statusBarFrame.origin.y = originY;
self.fStatusBar.view.frame = statusBarFrame;
[contentView addSubview:self.fStatusBar.view];
}
if ([self.fDefaults boolForKey:@"FilterBar"])
{
self.fFilterBar = [[FilterBarController alloc] init];
NSRect filterBarFrame = self.fFilterBar.view.frame;
filterBarFrame.size.width = windowSize.width;
originY -= FILTER_BAR_HEIGHT;
filterBarFrame.origin.y = originY;
self.fFilterBar.view.frame = filterBarFrame;
[contentView addSubview:self.fFilterBar.view];
}
NSScrollView* scrollView = self.fTableView.enclosingScrollView;
[contentView addSubview:scrollView];
[contentView addSubview:self.fActionButton];
[contentView addSubview:self.fSpeedLimitButton];
[contentView addSubview:self.fClearCompletedButton];
[contentView addSubview:self.fTotalTorrentsField];
//window is updated and animated in fullUpdateUI --> applyFilter --> setWindowSizeToFit
[self fullUpdateUI];
[self updateForAutoSize];
});
}
- (void)setWindowSizeToFit
{
NSScrollView* scrollView = self.fTableView.enclosingScrollView;
scrollView.hasVerticalScroller = NO;
[self.fWindow setFrame:self.sizedWindowFrame display:YES animate:YES];
scrollView.hasVerticalScroller = YES;
if ([self.fDefaults boolForKey:@"AutoSize"])
{
if (!self.isFullScreen)
{
[self setWindowMinMaxToCurrent];
}
}
}
- (void)updateForAutoSize
{
if ([self.fDefaults boolForKey:@"AutoSize"] && !self.isFullScreen)
{
[self setWindowSizeToFit];
}
else
{
NSSize contentMinSize = self.fWindow.contentMinSize;
contentMinSize.height = self.minWindowContentSizeAllowed;
self.fWindow.contentMinSize = contentMinSize;
NSSize contentMaxSize = self.fWindow.contentMaxSize;
contentMaxSize.height = FLT_MAX;
self.fWindow.contentMaxSize = contentMaxSize;
}
}
- (void)setWindowMinMaxToCurrent
{
CGFloat const height = NSHeight(self.fWindow.contentView.frame);
NSSize minSize = self.fWindow.contentMinSize, maxSize = self.fWindow.contentMaxSize;
minSize.height = height;
maxSize.height = height;
self.fWindow.contentMinSize = minSize;
self.fWindow.contentMaxSize = maxSize;
}
- (NSRect)sizedWindowFrame
{
NSRect windowFrame = self.fWindow.frame;
NSScrollView* scrollView = self.fTableView.enclosingScrollView;
CGFloat titleBarHeight = self.titlebarHeight;
CGFloat scrollViewHeight = self.scrollViewHeight;
CGFloat componentHeight = [self mainWindowComponentHeight];
//update window frame
NSSize windowSize = [scrollView convertSize:windowFrame.size fromView:nil];
windowSize.height = titleBarHeight + componentHeight + scrollViewHeight + BOTTOM_BAR_HEIGHT;
//update scrollview
NSRect scrollViewFrame = scrollView.frame;
scrollViewFrame.size.height = scrollViewHeight;
//we can't call minSize, since it might be set to the current size (auto size)
CGFloat const minHeight = self.minWindowContentSizeAllowed +
(NSHeight(self.fWindow.frame) - NSHeight(self.fWindow.contentView.frame)); //contentView to window
if (windowSize.height <= minHeight)
{
windowSize.height = minHeight;
}
else
{
NSScreen* screen = self.fWindow.screen;
if (screen && !self.isFullScreen)
{
NSSize maxSize = screen.frame.size;
maxSize.height -= titleBarHeight;
maxSize.height -= BOTTOM_BAR_HEIGHT;
if (self.fStatusBar)
{
maxSize.height -= STATUS_BAR_HEIGHT;
}
if (self.fFilterBar)
{
maxSize.height -= FILTER_BAR_HEIGHT;
}
if (windowSize.height > maxSize.height)
{
windowSize.height = maxSize.height;
//recalculate scrollview height
scrollViewFrame.size.height = self.fullScreenScrollViewHeight;
}
}
}
//commit scrollview changes
scrollViewFrame.origin.y = BOTTOM_BAR_HEIGHT;
[scrollView setFrame:scrollViewFrame];
windowFrame.origin.y -= (windowSize.height - windowFrame.size.height);
windowFrame.size.height = windowSize.height;
return windowFrame;
}
- (CGFloat)titlebarHeight
{
return self.fWindow.frame.size.height - [self.fWindow contentRectForFrameRect:self.fWindow.frame].size.height;
}
- (CGFloat)mainWindowComponentHeight
{
CGFloat height = 0;
if (self.fStatusBar)
{
height += STATUS_BAR_HEIGHT;
}
if (self.fFilterBar)
{
height += FILTER_BAR_HEIGHT;
}
return height;
}
- (CGFloat)scrollViewHeight
{
if (self.isFullScreen)
{
return self.fullScreenScrollViewHeight;
}
if ([self.fDefaults boolForKey:@"AutoSize"])
{
NSUInteger groups = (self.fDisplayedTorrents.count > 0 && ![self.fDisplayedTorrents[0] isKindOfClass:[Torrent class]]) ?
self.fDisplayedTorrents.count :
0;
CGFloat height = (GROUP_SEPARATOR_HEIGHT + self.fTableView.intercellSpacing.height) * groups +
(self.fTableView.rowHeight + self.fTableView.intercellSpacing.height) * (self.fTableView.numberOfRows - groups);
return height;
}
return NSHeight(self.fTableView.enclosingScrollView.frame);
}
- (CGFloat)fullScreenScrollViewHeight
{
return self.fWindow.frame.size.height - self.titlebarHeight - self.mainWindowComponentHeight - BOTTOM_BAR_HEIGHT;
}
- (CGFloat)minWindowContentSizeAllowed
{
CGFloat contentMinHeight = self.fTableView.rowHeight + self.fTableView.intercellSpacing.height +
self.mainWindowComponentHeight + BOTTOM_BAR_HEIGHT;
return contentMinHeight;
}
- (BOOL)isFullScreen
{
return (self.fWindow.styleMask & NSFullScreenWindowMask);
}
- (void)windowWillEnterFullScreen:(NSNotification*)notification
{
// temporarily disable AutoSize
NSSize contentMinSize = self.fWindow.contentMinSize;
contentMinSize.height = self.minWindowContentSizeAllowed;
self.fWindow.contentMinSize = contentMinSize;
NSSize contentMaxSize = self.fWindow.contentMaxSize;
contentMaxSize.height = FLT_MAX;
self.fWindow.contentMaxSize = contentMaxSize;
}
- (void)windowDidEnterFullScreen:(NSNotification*)notification
{
[self drawMainWindow];
}
- (void)windowWillExitFullScreen:(NSNotification*)notification
{
dispatch_async(dispatch_get_main_queue(), ^{
[self drawMainWindow];
});
}
- (void)windowDidExitFullScreen:(NSNotification*)notification
{
dispatch_async(dispatch_get_main_queue(), ^{
[self drawMainWindow];
});
}
@end

View file

@ -160,8 +160,8 @@ NSMutableSet* creatorWindowControllerSet = nil;
self.window.title = name;
//make window an auxillary view in fullscreen
[self.window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
//disable fullscreen support
[self.window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenNone];
self.fNameField.stringValue = name;
self.fNameField.toolTip = self.fPath.path;

View file

@ -66,8 +66,8 @@
self.window.title = NSLocalizedString(@"Message Log", "Message window -> title");
//make window an auxillary view in fullscreen
[window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
//disable fullscreen support
[window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenNone];
//set images and text for popup button items
[self.fLevelButton itemAtIndex:LEVEL_ERROR].title = NSLocalizedString(@"Error", "Message window -> level string");

View file

@ -202,8 +202,8 @@
self.window.restorationClass = [self class];
//make window an auxillary view in fullscreen
[self.window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
//disable fullscreen support
[self.window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenNone];
NSToolbar* toolbar = [[NSToolbar alloc] initWithIdentifier:@"Preferences Toolbar"];
toolbar.delegate = self;

View file

@ -69,8 +69,8 @@ tr_session* fLib = NULL;
self.window.title = NSLocalizedString(@"Statistics", "Stats window -> title");
//make window an auxillary view in fullscreen
[self.window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
//disable fullscreen support
[self.window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenNone];
//set label text
self.fUploadedLabelField.stringValue = [NSLocalizedString(@"Uploaded", "Stats window -> label") stringByAppendingString:@":"];