diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..4a192f33 --- /dev/null +++ b/.clang-format @@ -0,0 +1,32 @@ +BasedOnStyle: LLVM +UseTab: Always +TabWidth: 4 +IndentWidth: 4 +AlignEscapedNewlinesLeft: true +AllowShortIfStatementsOnASingleLine: false +ColumnLimit: 0 +IndentCaseLabels: true +ObjCBlockIndentWidth: 4 + +# Like Stroustrup but do not wrap braces after function definitions. +BreakBeforeBraces: Custom +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: true + BeforeElse: true + IndentBraces: false + +DerivePointerAlignment: false +PointerAlignment: Right + +AllowShortFunctionsOnASingleLine: Empty +AllowShortBlocksOnASingleLine: true +ObjCSpaceAfterProperty: true +SpacesInContainerLiterals: false diff --git a/Common/MenuMeterCPU.h b/Common/MenuMeterCPU.h index aee71dcc..a18e6965 100644 --- a/Common/MenuMeterCPU.h +++ b/Common/MenuMeterCPU.h @@ -1,154 +1,149 @@ // // MenuMeterCPU.h // -// Constants and other definitions for the CPU Meter +// Constants and other definitions for the CPU Meter // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // /////////////////////////////////////////////////////////////// // -// Constants +// Constants // /////////////////////////////////////////////////////////////// // Widths of the various displays -#define kCPUPercentDisplayBorderWidth 2 -#define kCPUThermometerDisplayWidth 11.0f -#define kCPUDisplayMultiProcGapWidth 5 -#define kCPULabelOnlyWidth 25 +#define kCPUPercentDisplayBorderWidth 2 +#define kCPUThermometerDisplayWidth 9 +#define kCPUDisplayMultiProcGapWidth 1 +#define kCPULabelOnlyWidth 25 // Menu item indexes -#define kCPUUptimeInfoMenuIndex 4 -#define kCPUTaskInfoMenuIndex 6 -#define kCPULoadInfoMenuIndex 8 -#define kCPUPowerLimitInfoMenuIndex 10 -#define kCPUProcessLabelMenuIndex 11 -#define kCPUProcessMenuIndex (kCPUProcessLabelMenuIndex + 1) +#define kCPUUptimeInfoMenuIndex 4 +#define kCPUTaskInfoMenuIndex 6 +#define kCPULoadInfoMenuIndex 8 +#define kCPUPowerLimitInfoMenuIndex 10 +#define kCPUProcessLabelMenuIndex 11 +#define kCPUProcessMenuIndex (kCPUProcessLabelMenuIndex + 1) /////////////////////////////////////////////////////////////// // -// Preference information +// Preference information // /////////////////////////////////////////////////////////////// // Pref dictionary keys -#define kCPUIntervalPref @"CPUInterval" -#define kCPUDisplayModePref @"CPUDisplayMode" -#define kCPUPercentDisplayPref @"CPUPercentDisplayMode" -#define kCPUMaxProcessCountPref @"CPUMaxProcessCount" -#define kCPUGraphLengthPref @"CPUGraphLength" -#define kCPUHorizontalRowsPref @"CPUHorizontalRows" -#define kCPUMenuWidthPref @"CPUMenuWidth" -#define kCPUAvgAllProcsPref @"CPUAverageMultiProcs" -#define kCPUSumAllProcsPercentPref @"CPUSumAllProcsPercent" +extern NSString *kCPUIntervalPref; +extern NSString *kCPUDisplayModePref; +extern NSString *kCPUPercentDisplayPref; +extern NSString *kCPUMaxProcessCountPref; +extern NSString *kCPUGraphLengthPref; +extern NSString *kCPUHorizontalRowsPref; +extern NSString *kCPUMenuWidthPref; +extern NSString *kCPUAvgAllProcsPref; +extern NSString *kCPUSumAllProcsPercentPref; // Note that "Lower Half" is now reused to show only physical cores -#define kCPUAvgLowerHalfProcsPref @"CPUAverageLowerHalfProcs" -#define kCPUSortByUsagePref @"CPUSortByUsage" -#define kCPUSystemColorPref @"CPUSystemColor" -#define kCPUUserColorPref @"CPUUserColor" -#define kCPUPowerMatePref @"CPUPowerMate" -#define kCPUPowerMateMode @"CPUPowerMateMode" -#define kCPUShowTemperature @"CPUTemperature" -#define kCPUTemperatureColor @"CPUTemperatureColor" -#define kCPUTemperatureSensor @"CPUTemperatureSensor" -#define kCPUTemperatureSensorDefault @"CPUTemperatureSensorDefault" -#define kCPUTemperatureUnit @"CPUTemperatureUnit" +extern NSString *kCPUAvgLowerHalfProcsPref; +extern NSString *kCPUSortByUsagePref; +extern NSString *kCPUSystemColorPref; +extern NSString *kCPUUserColorPref; +extern NSString *kCPUPowerMatePref; +extern NSString *kCPUPowerMateMode; +extern NSString *kCPUShowTemperature; +extern NSString *kCPUTemperatureColor; +extern NSString *kCPUTemperatureSensor; +extern NSString *kCPUTemperatureSensorDefault; +extern NSString *kCPUTemperatureUnit; #define kCPUTemperatureUnitCelsius 0 #define kCPUTemperatureUnitFahrenheit 1 // Display modes enum { - kCPUDisplayPercent = 1, - kCPUDisplayGraph = 2, - kCPUDisplayThermometer = 4, - kCPUDisplayHorizontalThermometer = 8 + kCPUDisplayPercent = 1, + kCPUDisplayGraph = 2, + kCPUDisplayThermometer = 4, + kCPUDisplayHorizontalThermometer = 8 }; -#define kCPUDisplayDefault kCPUDisplayPercent +#define kCPUDisplayDefault kCPUDisplayPercent // Percent display modes enum { - kCPUPercentDisplayLarge = 0, + kCPUPercentDisplayLarge = 0, kCPUPercentDisplaySmall, kCPUPercentDisplaySplit }; -#define kCPUPercentDisplayDefault kCPUPercentDisplaySmall +#define kCPUPercentDisplayDefault kCPUPercentDisplaySmall // Process info -#define kCPUProcessCountMin 0 -#define kCPUrocessCountMax 25 -#define kCPUProcessCountDefault 5 +#define kCPUProcessCountMin 0 +#define kCPUrocessCountMax 25 +#define kCPUProcessCountDefault 5 // PowerMate modes enum { - kCPUPowerMateGlow = 0, + kCPUPowerMateGlow = 0, kCPUPowerMatePulse, kCPUPowerMateInverseGlow, kCPUPowerMateInversePulse }; -#define kCPUPowerMateModeDefault kCPUPowerMateGlow +#define kCPUPowerMateModeDefault kCPUPowerMateGlow // Timer -#define kCPUUpdateIntervalMin 0.5f -#define kCPUUpdateIntervalMax 10.0f -#define kCPUUpdateIntervalDefault 1.0f +#define kCPUUpdateIntervalMin 0.5 +#define kCPUUpdateIntervalMax 10.0 +#define kCPUUpdateIntervalDefault 1.0 // Graph display -#define kCPUGraphWidthMin 11 -#define kCPUGraphWidthMax 88 -#define kCPUGraphWidthDefault 33 +#define kCPUGraphWidthMin 11 +#define kCPUGraphWidthMax 88 +#define kCPUGraphWidthDefault 33 // Thermometer display -#define kCPUHorizontalRowsMin 1 -#define kCPUHorizontalRowsMax 8 -#define kCPUHorizontalRowsDefault 2 +#define kCPUHorizontalRowsMin 1 +#define kCPUHorizontalRowsMax 8 +#define kCPUHorizontalRowsDefault 2 // Menu width -#define kCPUMenuWidthMin 60 -#define kCPUMenuWidthMax 400 -#define kCPUMenuWidthDefault 120 +#define kCPUMenuWidthMin 60 +#define kCPUMenuWidthMax 400 +#define kCPUMenuWidthDefault 120 // Multiproc averaging -#define kCPUAvgAllProcsDefault NO +#define kCPUAvgAllProcsDefault NO // Multiproc sum percentage -#define kCPUSumAllProcsPercentDefault NO +#define kCPUSumAllProcsPercentDefault NO // Least-utilized half of procs averaging -#define kCPUAvgLowerHalfProcsDefault NO +#define kCPUAvgLowerHalfProcsDefault NO // Sorting by usage -#define kCPUSortByUsageDefault NO +#define kCPUSortByUsageDefault NO // PowerMate -#define kCPUPowerMateDefault NO +#define kCPUPowerMateDefault NO // Show CPU temperature -#define kCPUShowTemperatureDefault YES +#define kCPUShowTemperatureDefault YES // Colors - // Maraschino -#define kCPUSystemColorDefault [NSColor colorWithDeviceRed:1.0f green:0.0f blue:0.0f alpha:1.0f] - // Midnight blue -#define kCPUUserColorDefault [NSColor colorWithDeviceRed:0.0f green:0.0f blue:0.5f alpha:1.0f] - // Orange -#define kCPUTemperatureColorDefault [NSColor colorWithDeviceRed:1.0f green:0.647f blue:0.0f alpha:1.0f] - - - - - +// Maraschino +#define kCPUSystemColorDefault [NSColor systemRedColor] +// Midnight blue +#define kCPUUserColorDefault [NSColor systemBlueColor] +// Orange +#define kCPUTemperatureColorDefault [NSColor systemOrangeColor] diff --git a/Common/MenuMeterCPU.m b/Common/MenuMeterCPU.m new file mode 100644 index 00000000..d69aa0d0 --- /dev/null +++ b/Common/MenuMeterCPU.m @@ -0,0 +1,29 @@ +// +// MenuMeterCPU.m +// MenuMeters +// +// Created by Georg Seifert on 31.10.21. +// + +// Pref dictionary keys +NSString *kCPUIntervalPref = @"CPUInterval"; +NSString *kCPUDisplayModePref = @"CPUDisplayMode"; +NSString *kCPUPercentDisplayPref = @"CPUPercentDisplayMode"; +NSString *kCPUMaxProcessCountPref = @"CPUMaxProcessCount"; +NSString *kCPUGraphLengthPref = @"CPUGraphLength"; +NSString *kCPUHorizontalRowsPref = @"CPUHorizontalRows"; +NSString *kCPUMenuWidthPref = @"CPUMenuWidth"; +NSString *kCPUAvgAllProcsPref = @"CPUAverageMultiProcs"; +NSString *kCPUSumAllProcsPercentPref = @"CPUSumAllProcsPercent"; +// Note that "Lower Half" is now reused to show only physical cores +NSString *kCPUAvgLowerHalfProcsPref = @"CPUAverageLowerHalfProcs"; +NSString *kCPUSortByUsagePref = @"CPUSortByUsage"; +NSString *kCPUSystemColorPref = @"CPUSystemColor"; +NSString *kCPUUserColorPref = @"CPUUserColor"; +NSString *kCPUPowerMatePref = @"CPUPowerMate"; +NSString *kCPUPowerMateMode = @"CPUPowerMateMode"; +NSString *kCPUShowTemperature = @"CPUTemperature"; +NSString *kCPUTemperatureColor = @"CPUTemperatureColor"; +NSString *kCPUTemperatureSensor = @"CPUTemperatureSensor"; +NSString *kCPUTemperatureSensorDefault = @"CPUTemperatureSensorDefault"; +NSString *kCPUTemperatureUnit = @"CPUTemperatureUnit"; diff --git a/Common/MenuMeterDefaults.h b/Common/MenuMeterDefaults.h index 83b90a9c..25e443d2 100644 --- a/Common/MenuMeterDefaults.h +++ b/Common/MenuMeterDefaults.h @@ -1,150 +1,251 @@ // -// MenuMeterDefaults.h +// MenuMeterDefaults.h // -// Preference (defaults) file reader/writer +// Preference (defaults) file reader/writer // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -#import -#import #import "MenuMeters.h" +#import +#import @interface MenuMeterDefaults : NSObject #ifdef ELCAPITAN + - (BOOL)loadBoolPref:(NSString *)prefName defaultValue:(BOOL)defaultValue; + - (void)saveBoolPref:(NSString *)prefName value:(BOOL)value; #endif + (void)movePreferencesIfNecessary; -+ (MenuMeterDefaults*)sharedMenuMeterDefaults; -// Pref read/write -- (void)syncWithDisk; ++ (MenuMeterDefaults *)sharedMenuMeterDefaults; // CPU menu prefs + - (double)cpuInterval; + - (int)cpuDisplayMode; + - (int)cpuPercentDisplay; + - (int)cpuMaxProcessCount; + - (int)cpuGraphLength; + - (int)cpuHorizontalRows; + - (int)cpuMenuWidth; + - (BOOL)cpuAvgAllProcs; + - (BOOL)cpuSumAllProcsPercent; + - (BOOL)cpuAvgLowerHalfProcs; + - (BOOL)cpuSortByUsage; + - (BOOL)cpuPowerMate; + - (BOOL)cpuShowTemperature; + - (int)cpuPowerMateMode; + - (int)cpuTemperatureUnit; -- (NSString*)cpuTemperatureSensor; + +- (NSString *)cpuTemperatureSensor; + - (NSColor *)cpuSystemColor; + - (NSColor *)cpuUserColor; + - (NSColor *)cpuTemperatureColor; + - (void)saveCpuInterval:(double)interval; + - (void)saveCpuDisplayMode:(int)mode; + - (void)saveCpuPercentDisplay:(int)mode; + - (void)saveCpuMaxProcessCount:(int)maxCount; + - (void)saveCpuGraphLength:(int)length; + - (void)saveCpuHorizontalRows:(int)rows; + - (void)saveCpuMenuWidth:(int)width; + - (void)saveCpuAvgAllProcs:(BOOL)average; + - (void)saveCpuSumAllProcsPercent:(BOOL)sum; + - (void)saveCpuAvgLowerHalfProcs:(BOOL)average; + - (void)saveCpuSortByUsage:(BOOL)sort; + - (void)saveCpuPowerMate:(BOOL)active; + - (void)saveCpuTemperature:(BOOL)show; + - (void)saveCpuPowerMateMode:(int)mode; + - (void)saveCpuSystemColor:(NSColor *)color; + - (void)saveCpuUserColor:(NSColor *)color; + - (void)saveCpuTemperatureColor:(NSColor *)color; + - (void)saveCpuTemperatureUnit:(int)unit; -- (void)saveCpuTemperatureSensor:(NSString*)name; + +- (void)saveCpuTemperatureSensor:(NSString *)name; // Disk menu prefs + - (double)diskInterval; + - (int)diskImageset; + - (int)diskSelectMode; + - (BOOL)diskSpaceForceBaseTwo; + - (void)saveDiskInterval:(double)interval; + - (void)saveDiskImageset:(int)imageset; + - (void)saveDiskSelectMode:(int)mode; // Mem menu prefs + - (double)memInterval; + - (int)memDisplayMode; + - (BOOL)memUsedFreeLabel; + - (int)memGraphLength; + - (BOOL)memPageIndicator; + - (BOOL)memPressure; + - (NSColor *)memFreeColor; + - (NSColor *)memUsedColor; + - (NSColor *)memActiveColor; + - (NSColor *)memInactiveColor; + - (NSColor *)memWireColor; + - (NSColor *)memCompressedColor; + - (NSColor *)memPageInColor; + - (NSColor *)memPageOutColor; + - (void)saveMemInterval:(double)interval; + - (void)saveMemDisplayMode:(int)mode; + - (void)saveMemPageIndicator:(BOOL)indicator; + - (void)saveMemUsedFreeLabel:(BOOL)label; + - (void)saveMemPressure:(BOOL)label; + - (void)saveMemGraphLength:(int)length; + - (void)saveMemFreeColor:(NSColor *)color; + - (void)saveMemUsedColor:(NSColor *)color; + - (void)saveMemActiveColor:(NSColor *)color; + - (void)saveMemInactiveColor:(NSColor *)color; + - (void)saveMemWireColor:(NSColor *)color; + - (void)saveMemCompressedColor:(NSColor *)color; + - (void)saveMemPageInColor:(NSColor *)color; + - (void)saveMemPageOutColor:(NSColor *)color; // Net menu prefs + - (double)netInterval; + - (int)netDisplayMode; + - (int)netDisplayOrientation; + - (int)netScaleMode; + - (int)netScaleCalc; + - (BOOL)netThroughputLabel; + - (BOOL)netThroughput1KBound; + - (BOOL)netThroughputBits; + - (int)netGraphStyle; + - (int)netGraphLength; + - (NSColor *)netTransmitColor; + - (NSColor *)netReceiveColor; + - (NSColor *)netInactiveColor; + - (NSString *)netPreferInterface; + - (void)saveNetInterval:(double)interval; + - (void)saveNetDisplayMode:(int)mode; + - (void)saveNetDisplayOrientation:(int)orient; + - (void)saveNetScaleMode:(int)mode; + - (void)saveNetScaleCalc:(int)calc; + - (void)saveNetThroughputLabel:(BOOL)label; + - (void)saveNetThroughput1KBound:(BOOL)bound; + - (void)saveNetThroughputBits:(BOOL)bits; + - (void)saveNetGraphStyle:(int)style; + - (void)saveNetGraphLength:(int)length; + - (void)saveNetTransmitColor:(NSColor *)color; + - (void)saveNetReceiveColor:(NSColor *)color; + - (void)saveNetInactiveColor:(NSColor *)color; + - (void)saveNetPreferInterface:(NSString *)interface; @end diff --git a/Common/MenuMeterDefaults.m b/Common/MenuMeterDefaults.m index 03704ce0..3198eb04 100644 --- a/Common/MenuMeterDefaults.m +++ b/Common/MenuMeterDefaults.m @@ -1,141 +1,163 @@ // -// MenuMeterDefaults.m +// MenuMeterDefaults.m // -// Preference (defaults) file reader/writer +// Preference (defaults) file reader/writer // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #import "MenuMeterDefaults.h" #import "MenuMeterCPU.h" -#import "MenuMeterMem.h" #import "MenuMeterDisk.h" +#import "MenuMeterMem.h" #import "MenuMeterNet.h" - /////////////////////////////////////////////////////////////// // -// Private +// Private // /////////////////////////////////////////////////////////////// @interface MenuMeterDefaults (PrivateMethods) - // Datatype read/write + - (double)loadDoublePref:(NSString *)prefName lowBound:(double)lowBound - highBound:(double)highBound defaultValue:(double)defaultValue; + highBound:(double)highBound + defaultValue:(double)defaultValue; + - (void)saveDoublePref:(NSString *)prefName value:(double)value; + - (int)loadIntPref:(NSString *)prefName lowBound:(int)lowBound - highBound:(int)highBound defaultValue:(int)defaultValue; + highBound:(int)highBound + defaultValue:(int)defaultValue; + - (void)saveIntPref:(NSString *)prefName value:(int)value; + - (int)loadBitFlagPref:(NSString *)prefName validFlags:(int)flags - defaultValue:(int)defaultValue; + defaultValue:(int)defaultValue; + - (void)saveBitFlagPref:(NSString *)prefName value:(int)value; #ifndef ELCAPITAN + - (BOOL)loadBoolPref:(NSString *)prefName defaultValue:(BOOL)defaultValue; + - (void)saveBoolPref:(NSString *)prefName value:(BOOL)value; #endif + - (NSColor *)loadColorPref:(NSString *)prefName defaultValue:(NSColor *)defaultValue; -- (void)saveColorPref:(NSString *)prefname value:(NSColor *)value; + +- (void)saveColorPref:(NSString *)prefName value:(NSColor *)value; + - (NSString *)loadStringPref:(NSString *)prefName defaultValue:(NSString *)defaultValue; + - (void)saveStringPref:(NSString *)prefName value:(NSString *)value; @end /////////////////////////////////////////////////////////////// // -// init/dealloc +// init/dealloc // /////////////////////////////////////////////////////////////// -@implementation MenuMeterDefaults +@implementation MenuMeterDefaults { + int _cpuDisplayMode; + BOOL _cpuAvgAllProcs; + int _cpuGraphLength; + int _cpuPercentDisplay; +} + #define kMigratedFromRagingMenaceToYujitach @"migratedFromRagingMenaceToYujitach" -+ (void)movePreferencesIfNecessary -{ - if([[NSUserDefaults standardUserDefaults] boolForKey:kMigratedFromRagingMenaceToYujitach]) - return; - NSData*data=[NSData dataWithContentsOfFile:[[NSString stringWithFormat:@"~/Library/Preferences/%@.plist", kMenuMeterDefaultsDomain] stringByExpandingTildeInPath]]; - if(data){ - NSError*error=nil; - NSDictionary*dict=[NSPropertyListSerialization propertyListWithData:data options:NSPropertyListImmutable format:nil error:&error]; - if(dict){ - NSData*defaultData=[NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:kMenuMeterDefaultsDomain ofType:@"plist"]]; - NSDictionary*defaultDict=[NSPropertyListSerialization propertyListWithData:defaultData options:NSPropertyListImmutable format:nil error:nil]; - for(NSString*key in [dict allKeys]){ - NSLog(@"migrating %@", key); - NSObject*value=[dict objectForKey:key]; - NSObject*defaultValue=[defaultDict objectForKey:key]; - if([value isEqualTo:defaultValue]){ - NSLog(@"\t%@ has default value; no need to copy",key); - }else{ - NSLog(@"\t%@ has non-default value; copying",key); - [[NSUserDefaults standardUserDefaults] setObject:[dict objectForKey:key] forKey:key]; - } - } - }else{ - NSLog(@"error reading old pref plist: %@",error); - } - } - [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kMigratedFromRagingMenaceToYujitach]; + ++ (void)movePreferencesIfNecessary { + if ([[NSUserDefaults standardUserDefaults] boolForKey:kMigratedFromRagingMenaceToYujitach]) + return; + NSData *data = [NSData dataWithContentsOfFile:[[NSString stringWithFormat:@"~/Library/Preferences/%@.plist", kMenuMeterDefaultsDomain] stringByExpandingTildeInPath]]; + if (data) { + NSError *error = nil; + NSDictionary *dict = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListImmutable format:nil error:&error]; + if (dict) { + NSData *defaultData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:kMenuMeterDefaultsDomain ofType:@"plist"]]; + NSDictionary *defaultDict = [NSPropertyListSerialization propertyListWithData:defaultData options:NSPropertyListImmutable format:nil error:nil]; + for (NSString *key in [dict allKeys]) { + NSLog(@"migrating %@", key); + NSObject *value = [dict objectForKey:key]; + NSObject *defaultValue = [defaultDict objectForKey:key]; + if ([value isEqualTo:defaultValue]) { + NSLog(@"\t%@ has default value; no need to copy", key); + } + else { + NSLog(@"\t%@ has non-default value; copying", key); + [[NSUserDefaults standardUserDefaults] setObject:[dict objectForKey:key] forKey:key]; + } + } + } + else { + NSLog(@"error reading old pref plist: %@", error); + } + } + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kMigratedFromRagingMenaceToYujitach]; } -+ (MenuMeterDefaults*)sharedMenuMeterDefaults -{ - static MenuMeterDefaults*foo=nil; - if(!foo){ - foo=[[MenuMeterDefaults alloc] init]; - } - return foo; + ++ (MenuMeterDefaults *)sharedMenuMeterDefaults { + static MenuMeterDefaults *foo = nil; + if (!foo) { + foo = [[MenuMeterDefaults alloc] init]; + } + return foo; } -- (id)init { + +- (instancetype)init { // Allow super to init self = [super init]; if (!self) { return nil; } - - // Send on back + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resetCaches:) name:NSUserDefaultsDidChangeNotification object:NULL]; + [self resetCaches:self]; return self; } // init - (void)dealloc { - // Save back - [self syncWithDisk]; - - // Super do its thing + [[NSNotificationCenter defaultCenter] removeObserver:self]; } // dealloc /////////////////////////////////////////////////////////////// // -// Pref read/write +// Cache // /////////////////////////////////////////////////////////////// -- (void)syncWithDisk { -} // syncFromDisk +- (void)resetCaches:(id)sender { + _cpuDisplayMode = -1; + _cpuAvgAllProcs = [self loadBoolPref:kCPUAvgAllProcsPref defaultValue:kCPUAvgAllProcsDefault]; + _cpuGraphLength = -1; + _cpuPercentDisplay = -1; +} /////////////////////////////////////////////////////////////// // -// CPU menu prefs +// CPU menu prefs // /////////////////////////////////////////////////////////////// @@ -147,48 +169,60 @@ - (double)cpuInterval { } // cpuInterval - (int)cpuDisplayMode { - return [self loadBitFlagPref:kCPUDisplayModePref - validFlags:(kCPUDisplayPercent | kCPUDisplayGraph | kCPUDisplayThermometer | kCPUDisplayHorizontalThermometer) - defaultValue:kCPUDisplayDefault]; + if (_cpuDisplayMode > 0) { + return _cpuDisplayMode; + } + _cpuDisplayMode = [self loadBitFlagPref:kCPUDisplayModePref + validFlags:(kCPUDisplayPercent | kCPUDisplayGraph | kCPUDisplayThermometer | kCPUDisplayHorizontalThermometer) + defaultValue:kCPUDisplayDefault]; + return _cpuDisplayMode; } // cpuDisplayMode - (int)cpuPercentDisplay { - return [self loadIntPref:kCPUPercentDisplayPref - lowBound:kCPUPercentDisplayLarge - highBound:kCPUPercentDisplaySplit - defaultValue:kCPUPercentDisplayDefault]; + if (_cpuPercentDisplay >= 0) { + return _cpuPercentDisplay; + } + _cpuPercentDisplay = [self loadIntPref:kCPUPercentDisplayPref + lowBound:kCPUPercentDisplayLarge + highBound:kCPUPercentDisplaySplit + defaultValue:kCPUPercentDisplayDefault]; + return _cpuPercentDisplay; } // cpuPercentDisplay - (int)cpuMaxProcessCount { - return [self loadIntPref:kCPUMaxProcessCountPref - lowBound:kCPUProcessCountMin - highBound:kCPUrocessCountMax - defaultValue:kCPUProcessCountDefault]; + return [self loadIntPref:kCPUMaxProcessCountPref + lowBound:kCPUProcessCountMin + highBound:kCPUrocessCountMax + defaultValue:kCPUProcessCountDefault]; } // cpuMaxProcessCount - (int)cpuGraphLength { - return [self loadIntPref:kCPUGraphLengthPref - lowBound:kCPUGraphWidthMin - highBound:kCPUGraphWidthMax - defaultValue:kCPUGraphWidthDefault]; + if (_cpuGraphLength > 0) { + return _cpuGraphLength; + } + _cpuGraphLength = [self loadIntPref:kCPUGraphLengthPref + lowBound:kCPUGraphWidthMin + highBound:kCPUGraphWidthMax + defaultValue:kCPUGraphWidthDefault]; + return _cpuGraphLength; } // cpuGraphLength - (int)cpuHorizontalRows { - return [self loadIntPref:kCPUHorizontalRowsPref - lowBound:kCPUHorizontalRowsMin - highBound:kCPUHorizontalRowsMax - defaultValue:kCPUHorizontalRowsDefault]; + return [self loadIntPref:kCPUHorizontalRowsPref + lowBound:kCPUHorizontalRowsMin + highBound:kCPUHorizontalRowsMax + defaultValue:kCPUHorizontalRowsDefault]; } // cpuHorizontalRows - (int)cpuMenuWidth { - return [self loadIntPref:kCPUMenuWidthPref - lowBound:kCPUMenuWidthMin - highBound:kCPUMenuWidthMax - defaultValue:kCPUMenuWidthDefault]; + return [self loadIntPref:kCPUMenuWidthPref + lowBound:kCPUMenuWidthMin + highBound:kCPUMenuWidthMax + defaultValue:kCPUMenuWidthDefault]; } // cpuMenuWidth - (BOOL)cpuAvgAllProcs { - return [self loadBoolPref:kCPUAvgAllProcsPref defaultValue:kCPUAvgAllProcsDefault]; + return _cpuAvgAllProcs; } // cpuAvgAllProcs - (BOOL)cpuSumAllProcsPercent { @@ -213,18 +247,29 @@ - (int)cpuPowerMateMode { highBound:kCPUPowerMateInversePulse defaultValue:kCPUPowerMateModeDefault]; } // cpuPowerMateMode + - (int)cpuTemperatureUnit { - return [self loadIntPref:kCPUTemperatureUnit - lowBound:kCPUTemperatureUnitCelsius - highBound:kCPUTemperatureUnitFahrenheit - defaultValue:kCPUTemperatureUnitCelsius]; + static CFStringRef key = CFSTR("AppleTemperatureUnit"); + static CFStringRef domain = CFSTR("Apple Global Domain"); + CFStringRef unit = CFPreferencesCopyValue(key, domain, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + if (!unit) { + return kCPUTemperatureUnitCelsius; + } + CFComparisonResult result = CFStringCompare(unit, CFSTR("Celsius"), 0); + if (unit) { + CFRelease(unit); + } + return result == kCFCompareEqualTo ? kCPUTemperatureUnitCelsius : kCPUTemperatureUnitFahrenheit; } -- (NSString*)cpuTemperatureSensor{ - return [self loadStringPref:kCPUTemperatureSensor defaultValue:kCPUTemperatureSensorDefault]; + +- (NSString *)cpuTemperatureSensor { + return [self loadStringPref:kCPUTemperatureSensor defaultValue:kCPUTemperatureSensorDefault]; } --(void)saveCpuTemperatureSensor:(NSString *)name{ - [self saveStringPref:kCPUTemperatureSensor value:name]; + +- (void)saveCpuTemperatureSensor:(NSString *)name { + [self saveStringPref:kCPUTemperatureSensor value:name]; } + - (NSColor *)cpuSystemColor { return [self loadColorPref:kCPUSystemColorPref defaultValue:kCPUSystemColorDefault]; } // cpuSystemColor @@ -234,12 +279,12 @@ - (NSColor *)cpuUserColor { } // cpuUserColor - (BOOL)cpuShowTemperature { - return [self loadBoolPref:kCPUShowTemperature defaultValue:kCPUShowTemperatureDefault]; + return [self loadBoolPref:kCPUShowTemperature defaultValue:kCPUShowTemperatureDefault]; } - (NSColor *)cpuTemperatureColor { - return [self loadColorPref:kCPUTemperatureColor defaultValue:kCPUTemperatureColorDefault]; -} //cpuTemperatureColor + return [self loadColorPref:kCPUTemperatureColor defaultValue:kCPUTemperatureColorDefault]; +} // cpuTemperatureColor - (void)saveCpuInterval:(double)interval { [self saveDoublePref:kCPUIntervalPref value:interval]; @@ -254,7 +299,7 @@ - (void)saveCpuPercentDisplay:(int)mode { } // saveCpuPercentSplit - (void)saveCpuMaxProcessCount:(int)maxCount { - [self saveIntPref:kCPUMaxProcessCountPref value:maxCount]; + [self saveIntPref:kCPUMaxProcessCountPref value:maxCount]; } // saveCpuMaxProcessCount - (void)saveCpuGraphLength:(int)length { @@ -262,11 +307,11 @@ - (void)saveCpuGraphLength:(int)length { } // saveCpuGraphLength - (void)saveCpuHorizontalRows:(int)rows { - [self saveIntPref:kCPUHorizontalRowsPref value:rows]; + [self saveIntPref:kCPUHorizontalRowsPref value:rows]; } // saveCpuHorizontalRows - (void)saveCpuMenuWidth:(int)rows { - [self saveIntPref:kCPUMenuWidthPref value:rows]; + [self saveIntPref:kCPUMenuWidthPref value:rows]; } // saveCpuMenuWidth - (void)saveCpuAvgAllProcs:(BOOL)average { @@ -294,15 +339,15 @@ - (void)saveCpuPowerMateMode:(int)mode { } // saveCpuPowerMateMode - (void)saveCpuTemperatureUnit:(int)unit { - [self saveIntPref:kCPUTemperatureUnit value:unit]; + [self saveIntPref:kCPUTemperatureUnit value:unit]; } // saveCpuPowerMateMode - (void)saveCpuTemperature:(BOOL)show { - [self saveBoolPref: kCPUShowTemperature value:show]; + [self saveBoolPref:kCPUShowTemperature value:show]; } // saveCpuTemperature - (void)saveCpuTemperatureColor:(NSColor *)color { - [self saveColorPref:kCPUTemperatureColor value:color]; + [self saveColorPref:kCPUTemperatureColor value:color]; } - (void)saveCpuSystemColor:(NSColor *)color { @@ -315,7 +360,7 @@ - (void)saveCpuUserColor:(NSColor *)color { /////////////////////////////////////////////////////////////// // -// Disk menu prefs +// Disk menu prefs // /////////////////////////////////////////////////////////////// @@ -359,7 +404,7 @@ - (void)saveDiskSelectMode:(int)mode { /////////////////////////////////////////////////////////////// // -// Mem menu prefs +// Mem menu prefs // /////////////////////////////////////////////////////////////// @@ -386,7 +431,7 @@ - (BOOL)memUsedFreeLabel { } // memUsedFreeLabel - (BOOL)memPressure { - return [self loadBoolPref:kMemPressurePref defaultValue:kMemPressureDefault]; + return [self loadBoolPref:kMemPressurePref defaultValue:kMemPressureDefault]; } // memUsedFreeLabel - (int)memGraphLength { @@ -441,7 +486,7 @@ - (void)saveMemUsedFreeLabel:(BOOL)label { } // saveMemUsedFreeLabel - (void)saveMemPressure:(BOOL)label { - [self saveBoolPref:kMemPressurePref value:label]; + [self saveBoolPref:kMemPressurePref value:label]; } // saveMemPressure - (void)saveMemPageIndicator:(BOOL)indicator { @@ -486,7 +531,7 @@ - (void)saveMemPageOutColor:(NSColor *)color { /////////////////////////////////////////////////////////////// // -// Net menu prefs +// Net menu prefs // /////////////////////////////////////////////////////////////// @@ -622,19 +667,18 @@ - (void)saveNetPreferInterface:(NSString *)interface { [self saveStringPref:kNetPreferInterfacePref value:interface]; } // saveNetPreferInterface - - /////////////////////////////////////////////////////////////// // -// Datatype read/write +// Datatype read/write // /////////////////////////////////////////////////////////////// - (double)loadDoublePref:(NSString *)prefName lowBound:(double)lowBound - highBound:(double)highBound defaultValue:(double)defaultValue { + highBound:(double)highBound + defaultValue:(double)defaultValue { double returnVal = defaultValue; - NSNumber *prefValue = [[NSUserDefaults standardUserDefaults] objectForKey:prefName]; + NSNumber *prefValue = [[NSUserDefaults standardUserDefaults] objectForKey:prefName]; if (prefValue && [prefValue isKindOfClass:[NSNumber class]]) { returnVal = [prefValue doubleValue]; // Floating point comparison needs some margin of error. Scale up @@ -650,84 +694,88 @@ - (double)loadDoublePref:(NSString *)prefName lowBound:(double)lowBound } // _loadDoublePref - (void)saveDoublePref:(NSString *)prefName value:(double)value { - [[NSUserDefaults standardUserDefaults] setDouble:value forKey:prefName]; + [[NSUserDefaults standardUserDefaults] setDouble:value forKey:prefName]; } // _saveDoublePref - (int)loadIntPref:(NSString *)prefName lowBound:(int)lowBound - highBound:(int)highBound defaultValue:(int)defaultValue { + highBound:(int)highBound + defaultValue:(int)defaultValue { + + Boolean keyExistsAndHasValidFormat = NO; + CFIndex returnValue = CFPreferencesGetAppIntegerValue((__bridge CFStringRef)prefName, kCFPreferencesCurrentApplication, &keyExistsAndHasValidFormat); - int returnValue=defaultValue; - if([[NSUserDefaults standardUserDefaults] objectForKey:prefName]){ - returnValue=(int)[[NSUserDefaults standardUserDefaults] integerForKey:prefName]; - } - if(returnValue > highBound || returnValue < lowBound){ - returnValue = defaultValue; - } - return (int) returnValue; + if (!keyExistsAndHasValidFormat) { + return defaultValue; + } + if (returnValue > highBound || returnValue < lowBound) { + returnValue = defaultValue; + } + return (int)returnValue; } // _loadIntPref -- (void)saveIntPref:(NSString *)prefname value:(int)value { - [[NSUserDefaults standardUserDefaults] setInteger:value forKey:prefname]; +- (void)saveIntPref:(NSString *)prefName value:(int)value { + [[NSUserDefaults standardUserDefaults] setInteger:value forKey:prefName]; } // _saveIntPref - (int)loadBitFlagPref:(NSString *)prefName validFlags:(int)flags defaultValue:(int)defaultValue { - if([[NSUserDefaults standardUserDefaults] objectForKey:prefName]){ - int returnValue=(int)[[NSUserDefaults standardUserDefaults] integerForKey:prefName]; - if (((returnValue | flags) == flags)) { - return returnValue; - } - } + Boolean keyExistsAndHasValidFormat = NO; + CFIndex returnValue = CFPreferencesGetAppIntegerValue((__bridge CFStringRef)prefName, kCFPreferencesCurrentApplication, &keyExistsAndHasValidFormat); + + if (!keyExistsAndHasValidFormat) { + return defaultValue; + } + if (((returnValue | flags) == flags)) { + return (int)returnValue; + } return defaultValue; } // _loadBitFlagPref - (void)saveBitFlagPref:(NSString *)prefName value:(int)value { - [[NSUserDefaults standardUserDefaults] setInteger:value forKey:prefName]; + [[NSUserDefaults standardUserDefaults] setInteger:value forKey:prefName]; } // _saveBitFlagPref - (BOOL)loadBoolPref:(NSString *)prefName defaultValue:(BOOL)defaultValue { - - if([[NSUserDefaults standardUserDefaults] objectForKey:prefName]){ - return [[NSUserDefaults standardUserDefaults] boolForKey:prefName]; - } - return defaultValue; + Boolean keyExistsAndHasValidFormat = NO; + Boolean result = CFPreferencesGetAppBooleanValue((__bridge CFStringRef)prefName, kCFPreferencesCurrentApplication, &keyExistsAndHasValidFormat); + return keyExistsAndHasValidFormat ? result : defaultValue; } // _loadBoolPref - (void)saveBoolPref:(NSString *)prefName value:(BOOL)value { - [[NSUserDefaults standardUserDefaults] setBool:value forKey:prefName]; + [[NSUserDefaults standardUserDefaults] setBool:value forKey:prefName]; } // _saveBoolPref - (NSColor *)loadColorPref:(NSString *)prefName defaultValue:(NSColor *)defaultValue { - NSData* data = [[NSUserDefaults standardUserDefaults] objectForKey:prefName]; - if(data){ - NSColor*color=[NSUnarchiver unarchiveObjectWithData:data]; - if(color){ - return color; - } + NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:prefName]; + if (data) { + NSColor *color = [NSUnarchiver unarchiveObjectWithData:data]; + if (color) { + return color; + } } - return defaultValue; + return defaultValue; } // _loadColorPref - (void)saveColorPref:(NSString *)prefName value:(NSColor *)value { if (value) { - [[NSUserDefaults standardUserDefaults] setObject:[NSArchiver archivedDataWithRootObject:value] forKey:prefName]; + [[NSUserDefaults standardUserDefaults] setObject:[NSArchiver archivedDataWithRootObject:value] forKey:prefName]; } } // _saveColorPref - (NSString *)loadStringPref:(NSString *)prefName defaultValue:(NSString *)defaultValue { - NSString*s=[[NSUserDefaults standardUserDefaults] objectForKey:prefName]; - if(s){ - return s; - } - return defaultValue; + NSString *s = [[NSUserDefaults standardUserDefaults] objectForKey:prefName]; + if (s) { + return s; + } + return defaultValue; } // _loadStringPref - (void)saveStringPref:(NSString *)prefName value:(NSString *)value { - [[NSUserDefaults standardUserDefaults] setObject:value forKey:prefName]; + [[NSUserDefaults standardUserDefaults] setObject:value forKey:prefName]; } // _saveStringPref @end diff --git a/Common/MenuMeterDisk.h b/Common/MenuMeterDisk.h index 3c2f5880..42e43aa4 100644 --- a/Common/MenuMeterDisk.h +++ b/Common/MenuMeterDisk.h @@ -1,34 +1,34 @@ // // MenuMeterDisk.h // -// Constants and other definitions for the Disk Meter +// Constants and other definitions for the Disk Meter // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // /////////////////////////////////////////////////////////////// // -// Constants +// Constants // /////////////////////////////////////////////////////////////// typedef enum { - kDiskActivityIdle = 0, + kDiskActivityIdle = 0, kDiskActivityRead, kDiskActivityWrite, kDiskActivityReadWrite @@ -36,47 +36,43 @@ typedef enum { /////////////////////////////////////////////////////////////// // -// Preference information +// Preference information // /////////////////////////////////////////////////////////////// // Pref dictionary keys -#define kDiskIntervalPref @"DiskInterval" -#define kDiskImageSetPref @"DiskImageSet" -#define kDiskSelectModePref @"DiskSelectMode" +#define kDiskIntervalPref @"DiskInterval" +#define kDiskImageSetPref @"DiskImageSet" +#define kDiskSelectModePref @"DiskSelectMode" // Hidden pref keys -#define kDiskSpaceForceBaseTwoPref @"DiskSpaceForceBaseTwo" +#define kDiskSpaceForceBaseTwoPref @"DiskSpaceForceBaseTwo" // Timer -#define kDiskUpdateIntervalMin 0.1f -#define kDiskUpdateIntervalMax 5.0f -#define kDiskUpdateIntervalDefault 0.3f +#define kDiskUpdateIntervalMin 0.1 +#define kDiskUpdateIntervalMax 5.0 +#define kDiskUpdateIntervalDefault 0.3 // Image sets -#define kDiskImageSets [NSArray arrayWithObjects: @"Color Arrows", @"Arrows", \ - @"Lights", @"Aqua Lights", @"Disk Arrows", \ - @"Disk Arrows (large)", nil] -#define kDiskDarkImageSets [NSArray arrayWithObjects: @"Dark Color Arrows", @"Dark Arrows", \ - @"Lights", @"Aqua Lights", @"Disk Arrows", \ - @"Disk Arrows (large)", nil] -#define kDiskImageSetDefault 0 -#define kDiskArrowsImageSet 4 -#define kDiskArrowsLargeImageSet 5 +#define kDiskImageSets [NSArray arrayWithObjects:@"Color Arrows", @"Arrows", \ + @"Lights", @"Aqua Lights", @"Disk Arrows", \ + @"Disk Arrows (large)", nil] +#define kDiskDarkImageSets [NSArray arrayWithObjects:@"Dark Color Arrows", @"Dark Arrows", \ + @"Lights", @"Aqua Lights", @"Disk Arrows", \ + @"Disk Arrows (large)", nil] +#define kDiskImageSetDefault 0 +#define kDiskArrowsImageSet 4 +#define kDiskArrowsLargeImageSet 5 // Select mode constants enum { - kDiskSelectModeOpen = 0, + kDiskSelectModeOpen = 0, kDiskSelectModeEject }; -#define kDiskSelectModeDefault kDiskSelectModeOpen +#define kDiskSelectModeDefault kDiskSelectModeOpen // Hidden pref defaults -#define kDiskSpaceForceBaseTwoDefault NO +#define kDiskSpaceForceBaseTwoDefault NO // View width, also menubar disk icon image width/height -#define kDiskViewWidth 16 - - - - +#define kDiskViewWidth 16 diff --git a/Common/MenuMeterMem.h b/Common/MenuMeterMem.h index 745de8ed..d9620c89 100644 --- a/Common/MenuMeterMem.h +++ b/Common/MenuMeterMem.h @@ -1,122 +1,120 @@ // // MenuMeterMem.h // -// Constants and other definitions for the Memory Meter +// Constants and other definitions for the Memory Meter // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // /////////////////////////////////////////////////////////////// // -// Constants +// Constants // /////////////////////////////////////////////////////////////// // Widths of the various displays -#define kMemPieDisplayWidth 17.0f -#define kMemNumberDisplayShortWidth 20.0f -#define kMemNumberDisplayLongWidth 26.0f -#define kMemNumberDisplayExtraLongWidth 34.0f -#define kMemThermometerDisplayWidth 11.0f -#define kMemPagingDisplayWidth 17.0f -#define kMemPagingDisplayGapWidth 4.0f +#define kMemPieDisplayWidth 17.0 +#define kMemNumberDisplayShortWidth 20.0 +#define kMemNumberDisplayLongWidth 26.0 +#define kMemNumberDisplayExtraLongWidth 34.0 +#define kMemThermometerDisplayWidth 11.0 +#define kMemPagingDisplayWidth 17.0 +#define kMemPagingDisplayGapWidth 4.0 // Menu item indexes -#define kMemUsageInfoMenuIndex 1 -#define kMemActiveWiredInfoMenuIndex 3 -#define kMemInactiveFreeInfoMenuIndex 4 -#define kMemCompressedInfoMenuIndex 5 -#define kMemVMPageInfoMenuIndex 7 -#define kMemVMCacheInfoMenuIndex 8 -#define kMemVMFaultInfoMenuIndex 9 -#define kMemMemPressureInfoMenuIndex 11 -#define kMemSwapCountInfoMenuIndex 13 -#define kMemSwapMaxCountInfoMenuIndex 14 -#define kMemSwapSizeInfoMenuIndex 15 +#define kMemUsageInfoMenuIndex 1 +#define kMemActiveWiredInfoMenuIndex 3 +#define kMemInactiveFreeInfoMenuIndex 4 +#define kMemCompressedInfoMenuIndex 5 +#define kMemVMPageInfoMenuIndex 7 +#define kMemVMCacheInfoMenuIndex 8 +#define kMemVMFaultInfoMenuIndex 9 +#define kMemMemPressureInfoMenuIndex 11 +#define kMemSwapCountInfoMenuIndex 13 +#define kMemSwapMaxCountInfoMenuIndex 14 +#define kMemSwapSizeInfoMenuIndex 15 /////////////////////////////////////////////////////////////// // -// Preference information +// Preference information // /////////////////////////////////////////////////////////////// // Pref dictionary keys -#define kMemIntervalPref @"MemInterval" -#define kMemDisplayModePref @"MemDisplayMode" -#define kMemUsedFreeLabelPref @"MemUsedFreeLabel" -#define kMemPressurePref @"MemPressure" -#define kMemPageIndicatorPref @"MemPagingIndicator" -#define kMemGraphLengthPref @"MemGraphLength" -#define kMemFreeColorPref @"MemFreeColor" -#define kMemUsedColorPref @"MemUsedColor" -#define kMemActiveColorPref @"MemActiveColor" -#define kMemInactiveColorPref @"MemInactiveColor" -#define kMemWireColorPref @"MemWireColor" -#define kMemCompressedColorPref @"MemCompressedColor" -#define kMemPageInColorPref @"MemPageInColor" -#define kMemPageOutColorPref @"MemPageOutColor" +#define kMemIntervalPref @"MemInterval" +#define kMemDisplayModePref @"MemDisplayMode" +#define kMemUsedFreeLabelPref @"MemUsedFreeLabel" +#define kMemPressurePref @"MemPressure" +#define kMemPageIndicatorPref @"MemPagingIndicator" +#define kMemGraphLengthPref @"MemGraphLength" +#define kMemFreeColorPref @"MemFreeColor" +#define kMemUsedColorPref @"MemUsedColor" +#define kMemActiveColorPref @"MemActiveColor" +#define kMemInactiveColorPref @"MemInactiveColor" +#define kMemWireColorPref @"MemWireColor" +#define kMemCompressedColorPref @"MemCompressedColor" +#define kMemPageInColorPref @"MemPageInColor" +#define kMemPageOutColorPref @"MemPageOutColor" // Display modes enum { - kMemDisplayPie = 1, + kMemDisplayPie = 1, kMemDisplayBar, kMemDisplayGraph, kMemDisplayNumber }; -#define kMemDisplayDefault kMemDisplayPie +#define kMemDisplayDefault kMemDisplayPie // Used/Free label -#define kMemUsedFreeLabelDefault YES +#define kMemUsedFreeLabelDefault YES -#define kMemPressureDefault NO +#define kMemPressureDefault NO // Page indicator -#define kMemPageIndicatorDefault NO +#define kMemPageIndicatorDefault NO // Timer -#define kMemUpdateIntervalMin 1.0 -#define kMemUpdateIntervalMax 60.0 -#define kMemUpdateIntervalDefault 10.0 +#define kMemUpdateIntervalMin 1.0 +#define kMemUpdateIntervalMax 60.0 +#define kMemUpdateIntervalDefault 10.0 // Graph display -#define kMemGraphWidthMin 11 -#define kMemGraphWidthMax 88 -#define kMemGraphWidthDefault 33 +#define kMemGraphWidthMin 11 +#define kMemGraphWidthMax 88 +#define kMemGraphWidthDefault 33 // Colors - // Clover -#define kMemFreeColorDefault [NSColor colorWithDeviceRed:0.0f green:0.5f blue:0.0f alpha:1.0f] - // Cayenne -#define kMemUsedColorDefault [NSColor colorWithDeviceRed:0.5f green:0.0f blue:0.0f alpha:1.0f] - // Lime -#define kMemActiveColorDefault [NSColor colorWithDeviceRed:0.5f green:1.0f blue:0.0f alpha:1.0f] - // Color between Aluminum and Magnesium - // (used to be Alumnium, but that was a bit dark) -#define kMemInactiveColorDefault [NSColor colorWithDeviceRed:0.7f green:0.7f blue:0.7f alpha:1.0f] - // Orchid -#define kMemWireColorDefault [NSColor colorWithDeviceRed:0.4f green:0.4f blue:1.0f alpha:1.0f] - // Maroon -#define kMemCompressedColorDefault [NSColor colorWithDeviceRed:0.5f green:0.0f blue:0.25f alpha:1.0f] - // Blue -#define kMemPageInColorDefault [NSColor blueColor] - // Red -#define kMemPageOutColorDefault [NSColor redColor] - // Black -#define kMemPageRateColorDefault [NSColor blackColor] - - +// Clover +#define kMemFreeColorDefault [NSColor colorWithDeviceRed:0.0 green:0.5 blue:0.0 alpha:1.0] +// Cayenne +#define kMemUsedColorDefault [NSColor colorWithDeviceRed:0.5 green:0.0 blue:0.0 alpha:1.0] +// Lime +#define kMemActiveColorDefault [NSColor colorWithDeviceRed:0.5 green:1.0 blue:0.0 alpha:1.0] +// Color between Aluminum and Magnesium +// (used to be Alumnium, but that was a bit dark) +#define kMemInactiveColorDefault [NSColor colorWithDeviceRed:0.7 green:0.7 blue:0.7 alpha:1.0] +// Orchid +#define kMemWireColorDefault [NSColor colorWithDeviceRed:0.4 green:0.4 blue:1.0 alpha:1.0] +// Maroon +#define kMemCompressedColorDefault [NSColor colorWithDeviceRed:0.5 green:0.0 blue:0.25 alpha:1.0] +// Blue +#define kMemPageInColorDefault [NSColor blueColor] +// Red +#define kMemPageOutColorDefault [NSColor redColor] +// Black +#define kMemPageRateColorDefault [NSColor blackColor] diff --git a/Common/MenuMeterNet.h b/Common/MenuMeterNet.h index afbd7502..102b5e78 100644 --- a/Common/MenuMeterNet.h +++ b/Common/MenuMeterNet.h @@ -1,129 +1,125 @@ // // MenuMeterNet.h // -// Constants and other definitions for the Net Meter +// Constants and other definitions for the Net Meter // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // - /////////////////////////////////////////////////////////////// // -// Constants +// Constants // /////////////////////////////////////////////////////////////// // Widths of the various displays -#define kNetArrowDisplayWidth 13 +#define kNetArrowDisplayWidth 13 // #define kNetNumberDisplayGapWidth 2 -#define kNetDisplayGapWidth 2 +#define kNetDisplayGapWidth 2 // String for primary interface selection (primary interface) -#define kNetPrimaryInterface @"primary" +#define kNetPrimaryInterface @"primary" /////////////////////////////////////////////////////////////// // -// Preference information +// Preference information // /////////////////////////////////////////////////////////////// // Pref dictionary keys -#define kNetIntervalPref @"NetInterval" -#define kNetDisplayModePref @"NetDisplayMode" -#define kNetDisplayOrientationPref @"NetOrientation" -#define kNetThroughputLabelPref @"NetThroughputLabel" -#define kNetThroughput1KBoundPref @"NetThroughput1KBound" -#define kNetThroughputBitsPref @"NetThroughputBits" -#define kNetGraphStylePref @"NetGraphStyle" -#define kNetGraphLengthPref @"NetGraphLength" -#define kNetScaleModePref @"NetScaleMode" -#define kNetScaleCalcPref @"NetScaleCalc" -#define kNetPreferInterfacePref @"NetPreferInterface" -#define kNetTransmitColorPref @"NetTransmitColor" -#define kNetReceiveColorPref @"NetReceiveColor" -#define kNetInactiveColorPref @"NetInactiveColor" +#define kNetIntervalPref @"NetInterval" +#define kNetDisplayModePref @"NetDisplayMode" +#define kNetDisplayOrientationPref @"NetOrientation" +#define kNetThroughputLabelPref @"NetThroughputLabel" +#define kNetThroughput1KBoundPref @"NetThroughput1KBound" +#define kNetThroughputBitsPref @"NetThroughputBits" +#define kNetGraphStylePref @"NetGraphStyle" +#define kNetGraphLengthPref @"NetGraphLength" +#define kNetScaleModePref @"NetScaleMode" +#define kNetScaleCalcPref @"NetScaleCalc" +#define kNetPreferInterfacePref @"NetPreferInterface" +#define kNetTransmitColorPref @"NetTransmitColor" +#define kNetReceiveColorPref @"NetReceiveColor" +#define kNetInactiveColorPref @"NetInactiveColor" // Display modes enum { - kNetDisplayArrows = 1, - kNetDisplayThroughput = 2, - kNetDisplayGraph = 4 + kNetDisplayArrows = 1, + kNetDisplayThroughput = 2, + kNetDisplayGraph = 4 }; -#define kNetDisplayDefault kNetDisplayArrows +#define kNetDisplayDefault kNetDisplayArrows // Display orientation enum { - kNetDisplayOrientTxRx = 0, + kNetDisplayOrientTxRx = 0, kNetDisplayOrientRxTx }; -#define kNetDisplayOrientationDefault kNetDisplayOrientTxRx +#define kNetDisplayOrientationDefault kNetDisplayOrientTxRx // Timer -#define kNetUpdateIntervalMin 0.5 -#define kNetUpdateIntervalMax 20.0 -#define kNetUpdateIntervalDefault 2.0 +#define kNetUpdateIntervalMin 0.5 +#define kNetUpdateIntervalMax 20.0 +#define kNetUpdateIntervalDefault 2.0 // Net scaling types enum { - kNetScaleInterfaceSpeed = 0, + kNetScaleInterfaceSpeed = 0, kNetScalePeakTraffic }; -#define kNetScaleDefault kNetScaleInterfaceSpeed +#define kNetScaleDefault kNetScaleInterfaceSpeed // Net scaling calcs enum { - kNetScaleCalcLinear = 0, + kNetScaleCalcLinear = 0, kNetScaleCalcSquareRoot, kNetScaleCalcCubeRoot, kNetScaleCalcLog }; -#define kNetScaleCalcDefault kNetScaleCalcCubeRoot +#define kNetScaleCalcDefault kNetScaleCalcCubeRoot // Graph display -#define kNetGraphWidthMin 11 -#define kNetGraphWidthMax 88 -#define kNetGraphWidthDefault 33 +#define kNetGraphWidthMin 11 +#define kNetGraphWidthMax 88 +#define kNetGraphWidthDefault 33 // Net graph styles enum { - kNetGraphStyleStandard = 0, + kNetGraphStyleStandard = 0, kNetGraphStyleCentered, kNetGraphStyleOpposed, kNetGraphStyleInverseOpposed }; -#define kNetGraphStyleDefault kNetGraphStyleStandard +#define kNetGraphStyleDefault kNetGraphStyleStandard // Throughput label -#define kNetThroughputLabelDefault YES +#define kNetThroughputLabelDefault YES // Thoughput 1K bound -#define kNetThroughput1KBoundDefault NO +#define kNetThroughput1KBoundDefault NO // Thoughput Bits per second -#define kNetThroughputBitsDefault NO +#define kNetThroughputBitsDefault NO // Colors - // Moss green -#define kNetTransmitColorDefault [NSColor colorWithDeviceRed:0.0f green:0.5f blue:0.25f alpha:1.0f] - // Brick red -#define kNetReceiveColorDefault [NSColor colorWithDeviceRed:0.5f green:0.0f blue:0.0f alpha:1.0f] - // Light grey -#define kNetInactiveColorDefault [NSColor darkGrayColor] - - - +// Moss green +#define kNetTransmitColorDefault [NSColor systemGreenColor] +// Brick red +#define kNetReceiveColorDefault [NSColor systemRedColor] +// Light grey +#define kNetInactiveColorDefault [NSColor secondaryLabelColor] diff --git a/Common/MenuMeterPowerMate.h b/Common/MenuMeterPowerMate.h index 5fa4f8fe..3d400680 100644 --- a/Common/MenuMeterPowerMate.h +++ b/Common/MenuMeterPowerMate.h @@ -1,54 +1,58 @@ // // MenuMeterPowerMate.h // -// PowerMate support, based on sample code from Griffin +// PowerMate support, based on sample code from Griffin // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -#import #import -#import +#import #import +#import @interface MenuMeterPowerMate : NSObject { // IOKit connection - mach_port_t masterPort; - IONotificationPortRef notifyPort; - CFRunLoopSourceRef notifyRunSource; - io_iterator_t deviceMatchedIterator, - deviceTerminatedIterator; + mach_port_t masterPort; + IONotificationPortRef notifyPort; + CFRunLoopSourceRef notifyRunSource; + io_iterator_t deviceMatchedIterator, + deviceTerminatedIterator; // Connected PowerMate state - BOOL devicePresent; - IOUSBDeviceInterface **deviceInterface; + BOOL devicePresent; + IOUSBDeviceInterface **deviceInterface; // Glow ramping - double lastGlowLevel, - targetGlowLevel, - rampGlowStep; - NSTimer *rampTimer; + double lastGlowLevel, + targetGlowLevel, + rampGlowStep; + NSTimer *rampTimer; } // MenuMeterPowerMate + (BOOL)powermateAttached; + - (void)setGlow:(double)level; + - (void)setGlow:(double)level rampInterval:(NSTimeInterval)interval; + - (void)setPulse:(double)rate; + - (void)stopPulse; @end diff --git a/Common/MenuMeterPowerMate.m b/Common/MenuMeterPowerMate.m index 17fee4f9..d4826aa0 100644 --- a/Common/MenuMeterPowerMate.m +++ b/Common/MenuMeterPowerMate.m @@ -1,67 +1,69 @@ // // MenuMeterPowerMate.m // -// PowerMate support +// PowerMate support // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #import "MenuMeterPowerMate.h" #import - /////////////////////////////////////////////////////////////// // -// Private methods and constants +// Private methods and constants // /////////////////////////////////////////////////////////////// @interface MenuMeterPowerMate (PrivateMethods) --(void)glowRamp:(NSTimer *)timer; --(void)deviceMatched:(io_iterator_t)iterator; --(void)deviceTerminated:(io_iterator_t)iterator; + +- (void)glowRamp:(NSTimer *)timer; + +- (void)deviceMatched:(io_iterator_t)iterator; + +- (void)deviceTerminated:(io_iterator_t)iterator; @end #define kGlowRampInterval 0.05 - /////////////////////////////////////////////////////////////// // -// IOKit notification callbacks +// IOKit notification callbacks // /////////////////////////////////////////////////////////////// static void DeviceMatched(void *ref, io_iterator_t iterator) { - if (ref) [(__bridge MenuMeterPowerMate *)ref deviceMatched:iterator]; + if (ref) + [(__bridge MenuMeterPowerMate *)ref deviceMatched:iterator]; } // DeviceMatched static void DeviceTerminated(void *ref, io_iterator_t iterator) { - if (ref) [(__bridge MenuMeterPowerMate *)ref deviceTerminated:iterator]; + if (ref) + [(__bridge MenuMeterPowerMate *)ref deviceTerminated:iterator]; } // DeviceTerminated - /////////////////////////////////////////////////////////////// // -// init/dealloc +// init/dealloc // /////////////////////////////////////////////////////////////// @@ -70,9 +72,10 @@ @implementation MenuMeterPowerMate + (BOOL)powermateAttached { // Check for device - mach_port_t localMasterPort = 0; + mach_port_t localMasterPort = 0; kern_return_t err = IOMasterPort(MACH_PORT_NULL, &localMasterPort); - if ((err != KERN_SUCCESS) || !localMasterPort) return NO; + if ((err != KERN_SUCCESS) || !localMasterPort) + return NO; // Construct a matching dict CFMutableDictionaryRef matchingDict = IOServiceMatching("IOUSBDevice"); @@ -105,7 +108,7 @@ + (BOOL)powermateAttached { } // powermateAttached -- (id)init { +- (instancetype)init { self = [super init]; if (!self) { @@ -151,21 +154,21 @@ - (id)init { // Install notifications for Powermate devices err = IOServiceAddMatchingNotification(notifyPort, - kIOMatchedNotification, + kIOMatchedNotification, matchingDict, DeviceMatched, - (__bridge void *)(self), &deviceMatchedIterator); + (__bridge void *)(self), &deviceMatchedIterator); if (err != KERN_SUCCESS) { - CFRelease(terminatedDict); + CFRelease(terminatedDict); return nil; } - err = IOServiceAddMatchingNotification(notifyPort, - kIOTerminatedNotification, + err = IOServiceAddMatchingNotification(notifyPort, + kIOTerminatedNotification, terminatedDict, DeviceTerminated, - (__bridge void *)(self), &deviceTerminatedIterator); + (__bridge void *)(self), &deviceTerminatedIterator); if (err != KERN_SUCCESS) { return nil; } @@ -181,21 +184,26 @@ - (id)init { - (void)dealloc { - [rampTimer invalidate]; // Runloop releases - if (deviceInterface) (*deviceInterface)->Release(deviceInterface); - if (deviceMatchedIterator) IOObjectRelease(deviceMatchedIterator); - if (deviceTerminatedIterator) IOObjectRelease(deviceTerminatedIterator); + [rampTimer invalidate]; // Runloop releases + if (deviceInterface) + (*deviceInterface)->Release(deviceInterface); + if (deviceMatchedIterator) + IOObjectRelease(deviceMatchedIterator); + if (deviceTerminatedIterator) + IOObjectRelease(deviceTerminatedIterator); if (notifyRunSource) { CFRunLoopRemoveSource(CFRunLoopGetCurrent(), notifyRunSource, kCFRunLoopDefaultMode); } - if (notifyPort) IONotificationPortDestroy(notifyPort); - if (masterPort) mach_port_deallocate(mach_task_self(), masterPort); + if (notifyPort) + IONotificationPortDestroy(notifyPort); + if (masterPort) + mach_port_deallocate(mach_task_self(), masterPort); } // dealloc /////////////////////////////////////////////////////////////// // -// Public interface +// Public interface // /////////////////////////////////////////////////////////////// @@ -205,25 +213,29 @@ - (void)setGlow:(double)level { [rampTimer invalidate]; rampTimer = nil; - if (!(devicePresent && deviceInterface)) return; + if (!(devicePresent && deviceInterface)) + return; // Sanity - if (level > 1.0) level = 1.0; - if (level < 0) level = 0; + if (level > 1.0) + level = 1.0; + if (level < 0) + level = 0; // Clear pulsing [self stopPulse]; // Store and clear ramp lastGlowLevel = level; - targetGlowLevel =level; + targetGlowLevel = level; rampGlowStep = 0; // Only 128 levels of glow UInt16 targetGlow = 128 * level; - if (targetGlow > 128) targetGlow = 128; + if (targetGlow > 128) + targetGlow = 128; - IOUSBDevRequest usbRequest; + IOUSBDevRequest usbRequest; usbRequest.bmRequestType = 0x41; usbRequest.bRequest = 0x01; usbRequest.wValue = 0x01; @@ -240,17 +252,21 @@ - (void)setGlow:(double)level rampInterval:(NSTimeInterval)interval { [rampTimer invalidate]; rampTimer = nil; - if (!(devicePresent && deviceInterface)) return; + if (!(devicePresent && deviceInterface)) + return; // Sanity - if (level > 1.0) level = 1.0; - if (level < 0) level = 0; + if (level > 1.0) + level = 1.0; + if (level < 0) + level = 0; // Clear pulsing [self stopPulse]; // We tick every kGlowRampInterval seconds, is the interval too short? - if (interval <= kGlowRampInterval) [self setGlow:level]; + if (interval <= kGlowRampInterval) + [self setGlow:level]; // Calc steps. We're happy with steps that are actually finer // than the device can handle. @@ -272,14 +288,17 @@ - (void)setGlow:(double)level rampInterval:(NSTimeInterval)interval { - (void)setPulse:(double)rate { - if (!(devicePresent && deviceInterface)) return; + if (!(devicePresent && deviceInterface)) + return; // Sanity - if (rate > 1.0) rate = 1.0; - if (rate < 0) rate = 0; + if (rate > 1.0) + rate = 1.0; + if (rate < 0) + rate = 0; // Turn on pulsing on - IOUSBDevRequest usbRequest; + IOUSBDevRequest usbRequest; usbRequest.bmRequestType = 0x41; usbRequest.bRequest = 0x01; usbRequest.wValue = 0x03; @@ -298,9 +317,11 @@ - (void)setPulse:(double)rate { uint8_t pulseRate = 24 * rate; if (pulseRate > 2) { usbRequest.wIndex = 0x02 | (pulseRate << 8); - } else if (pulseRate == 2) { + } + else if (pulseRate == 2) { usbRequest.wIndex = 0x0001; - } else { + } + else { usbRequest.wIndex = (2 - pulseRate) << 8; } (*deviceInterface)->DeviceRequest(deviceInterface, &usbRequest); @@ -309,8 +330,9 @@ - (void)setPulse:(double)rate { - (void)stopPulse { - if (!(devicePresent && deviceInterface)) return; - IOUSBDevRequest usbRequest; + if (!(devicePresent && deviceInterface)) + return; + IOUSBDevRequest usbRequest; usbRequest.bmRequestType = 0x41; usbRequest.bRequest = 0x01; usbRequest.wValue = 0x03; @@ -323,11 +345,11 @@ - (void)stopPulse { /////////////////////////////////////////////////////////////// // -// Timer callback +// Timer callback // /////////////////////////////////////////////////////////////// --(void)glowRamp:(NSTimer *)timer { +- (void)glowRamp:(NSTimer *)timer { // Sanity checks if (!(devicePresent && deviceInterface)) { @@ -338,18 +360,21 @@ -(void)glowRamp:(NSTimer *)timer { // Calc next level double newLevel = lastGlowLevel + rampGlowStep; - if (newLevel > 1.0) newLevel = 1.0; - if (newLevel < 0) newLevel = 0; + if (newLevel > 1.0) + newLevel = 1.0; + if (newLevel < 0) + newLevel = 0; // If we've met the target return to the normal code path if (rampGlowStep > 0) { if (newLevel > targetGlowLevel) { - [self setGlow:targetGlowLevel]; // Cancels timer + [self setGlow:targetGlowLevel]; // Cancels timer return; } - } else { + } + else { if (newLevel < targetGlowLevel) { - [self setGlow:targetGlowLevel]; // Cancels timer + [self setGlow:targetGlowLevel]; // Cancels timer return; } } @@ -357,9 +382,10 @@ -(void)glowRamp:(NSTimer *)timer { // Intermediate level set from here // Only 128 levels of glow UInt16 targetGlow = 128 * newLevel; - if (targetGlow > 128) targetGlow = 128; + if (targetGlow > 128) + targetGlow = 128; - IOUSBDevRequest usbRequest; + IOUSBDevRequest usbRequest; usbRequest.bmRequestType = 0x41; usbRequest.bRequest = 0x01; usbRequest.wValue = 0x01; @@ -374,14 +400,15 @@ -(void)glowRamp:(NSTimer *)timer { /////////////////////////////////////////////////////////////// // -// Device state changes +// Device state changes // /////////////////////////////////////////////////////////////// --(void)deviceMatched:(io_iterator_t)iterator { +- (void)deviceMatched:(io_iterator_t)iterator { io_service_t pmDevice = IOIteratorNext(iterator); - if (!pmDevice) return; + if (!pmDevice) + return; // Drain the iterator io_service_t otherDevice = IOIteratorNext(iterator); @@ -406,9 +433,7 @@ -(void)deviceMatched:(io_iterator_t)iterator { IOObjectRelease(pmDevice); return; } - HRESULT queryErr = (*plugInInterface)->QueryInterface(plugInInterface, - CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), - (LPVOID)&deviceInterface); + HRESULT queryErr = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID)&deviceInterface); IODestroyPlugInInterface(plugInInterface); if (queryErr || !deviceInterface) { IOObjectRelease(pmDevice); @@ -427,11 +452,12 @@ -(void)deviceMatched:(io_iterator_t)iterator { } // _deviceMatched: --(void)deviceTerminated:(io_iterator_t)iterator { +- (void)deviceTerminated:(io_iterator_t)iterator { // Assume any termination is our device (again, no attempt to handle // multiple devices) - if (deviceInterface) (*deviceInterface)->Release(deviceInterface); + if (deviceInterface) + (*deviceInterface)->Release(deviceInterface); deviceInterface = NULL; devicePresent = NO; diff --git a/Common/MenuMeterWorkarounds.h b/Common/MenuMeterWorkarounds.h index fafeb65e..c3bcbc56 100644 --- a/Common/MenuMeterWorkarounds.h +++ b/Common/MenuMeterWorkarounds.h @@ -1,30 +1,30 @@ // // MenuMeterWorkarounds.h // -// Various workarounds for old OS bugs that may not be applicable +// Various workarounds for old OS bugs that may not be applicable // (or compilable) on newer OS versions. To prevent conflicts // everything here is __private_extern__. // -// Copyright (c) 2009-2014 Alex Harper +// Copyright (c) 2009-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -#import #import +#import // OS version info __private_extern__ BOOL OSIsJaguarOrLater(void); @@ -38,4 +38,3 @@ __private_extern__ BOOL OSIsMavericksOrLater(void); __private_extern__ void LiveUpdateMenuItemTitleAndVisibility(NSMenu *, CFIndex, NSString *, BOOL); __private_extern__ void LiveUpdateMenuItemTitle(NSMenu *, CFIndex, NSString *); __private_extern__ void LiveUpdateMenu(NSMenu *); - diff --git a/Common/MenuMeterWorkarounds.m b/Common/MenuMeterWorkarounds.m index 709418b5..57ec57ce 100644 --- a/Common/MenuMeterWorkarounds.m +++ b/Common/MenuMeterWorkarounds.m @@ -1,26 +1,26 @@ // // MenuMeterWorkarounds.m // -// Various workarounds for old OS bugs that may not be applicable +// Various workarounds for old OS bugs that may not be applicable // (or compilable) on newer OS versions. To prevent conflicts // everything here is __private_extern__. // -// Copyright (c) 2009-2014 Alex Harper +// Copyright (c) 2009-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #import "MenuMeterWorkarounds.h" @@ -33,7 +33,7 @@ int64_t minorVersion; int64_t patchVersion; } NSOperatingSystemVersion; -#else +#else typedef struct { int32_t majorVersion; int32_t minorVersion; @@ -43,28 +43,30 @@ #endif @interface NSProcessInfo (MenuMetersWorkarounds) + - (BOOL)isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion)version; @end - static BOOL SystemVersionCompare(SInt32 gestVersion, int32_t major, int32_t minor) { #ifndef ELCAPITAN if ([NSProcessInfo instancesRespondToSelector:@selector(isOperatingSystemAtLeastVersion:)]) { #endif - NSOperatingSystemVersion version = { major, minor, 0 }; + NSOperatingSystemVersion version = {major, minor, 0}; return [[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:version]; #ifndef ELCAPITAN - } else { + } + else { SInt32 systemVersion = 0; OSStatus err = Gestalt(gestaltSystemVersion, &systemVersion); if ((err == noErr) && (systemVersion >= gestVersion)) { return YES; - } else { + } + else { return NO; } } #endif -} +} __private_extern__ BOOL OSIsJaguarOrLater(void) { return SystemVersionCompare(0x1020, 10, 2); @@ -91,7 +93,7 @@ __private_extern__ BOOL OSIsMavericksOrLater(void) { } __private_extern__ void LiveUpdateMenuItemTitle(NSMenu *menu, CFIndex index, NSString *title) { - LiveUpdateMenuItemTitleAndVisibility(menu, index, title, NO); + LiveUpdateMenuItemTitleAndVisibility(menu, index, title, NO); } __private_extern__ void LiveUpdateMenuItemTitleAndVisibility(NSMenu *menu, CFIndex index, NSString *title, BOOL hidden) { @@ -103,7 +105,8 @@ __private_extern__ void LiveUpdateMenuItemTitleAndVisibility(NSMenu *menu, CFInd // Guard against < 1 based values (such as the output of [NSMenu indexOfItem:] // when the item is not found. - if (index < 0) return; + if (index < 0) + return; #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 // The Carbon side is set first since setting it results in a empty @@ -111,13 +114,13 @@ __private_extern__ void LiveUpdateMenuItemTitleAndVisibility(NSMenu *menu, CFInd MenuRef carbonMenu = _NSGetCarbonMenu(menu); if (carbonMenu) { SetMenuItemTextWithCFString(carbonMenu, - index + 1, // Carbon menus 1-based index + index + 1, // Carbon menus 1-based index (CFStringRef)title); } #endif - if (title) - [[menu itemAtIndex:index] setTitle:title]; - [[menu itemAtIndex:index] setHidden:hidden]; + if (title) + [[menu itemAtIndex:index] setTitle:title]; + [[menu itemAtIndex:index] setHidden:hidden]; } // LiveUpdateMenuItemTitle @@ -131,4 +134,3 @@ __private_extern__ void LiveUpdateMenu(NSMenu *menu) { #endif } // LiveUpdateMenu - diff --git a/Common/MenuMeters.h b/Common/MenuMeters.h index 7cc89e1c..2717863a 100644 --- a/Common/MenuMeters.h +++ b/Common/MenuMeters.h @@ -1,97 +1,97 @@ // -// MenuMeters.h +// MenuMeters.h // -// Shared defines for the entire project +// Shared defines for the entire project // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #import "MenuMetersMenuExtraBase.h" /////////////////////////////////////////////////////////////// // -// Bundle information +// Bundle information // /////////////////////////////////////////////////////////////// // Bundle directory name of the preferences bundle #ifndef ELCAPITAN -#define kPrefBundleName @"MenuMeterDefaults.bundle" +#define kPrefBundleName @"MenuMeterDefaults.bundle" #else -#define kPrefBundleName @"MenuMetersApp.app/Contents/Resources/MenuMeterDefaults.bundle" +#define kPrefBundleName @"MenuMetersApp.app/Contents/Resources/MenuMeterDefaults.bundle" #endif // Bundle ID for the CPU menu extra -#define kCPUMenuBundleID @"com.ragingmenace.MenuMeterCPU" +#define kCPUMenuBundleID @"com.ragingmenace.MenuMeterCPU" // Bundle ID for the Disk menu extra -#define kDiskMenuBundleID @"com.ragingmenace.MenuMeterDisk" +#define kDiskMenuBundleID @"com.ragingmenace.MenuMeterDisk" // Bundle ID for the Memory menu extra -#define kMemMenuBundleID @"com.ragingmenace.MenuMeterMem" +#define kMemMenuBundleID @"com.ragingmenace.MenuMeterMem" // Bundle ID for the Net menu extra -#define kNetMenuBundleID @"com.ragingmenace.MenuMeterNet" +#define kNetMenuBundleID @"com.ragingmenace.MenuMeterNet" // Bundle information for the pref pane -#define kPrefPaneBundleID @"com.ragingmenace.MenuMeters" +#define kPrefPaneBundleID @"com.ragingmenace.MenuMeters" /////////////////////////////////////////////////////////////// // -// Preference information +// Preference information // /////////////////////////////////////////////////////////////// // Since all our bundles share a single pref file we don't use the default // suite (which would be based on our bundle) and instead we load a different // domain -#define kMenuMeterDefaultsDomain @"com.ragingmenace.MenuMeters" +#define kMenuMeterDefaultsDomain @"com.ragingmenace.MenuMeters" // Old name we no longer use -#define kMenuMeterObsoleteDomain @"MenuMeters" +#define kMenuMeterObsoleteDomain @"MenuMeters" // Pref versioning -#define kPrefVersionKey @"MenuMeterPrefVersion" -#define kCurrentPrefVersion 8 +#define kPrefVersionKey @"MenuMeterPrefVersion" +#define kCurrentPrefVersion 8 /////////////////////////////////////////////////////////////// // -// Notifications +// Notifications // /////////////////////////////////////////////////////////////// // Preferences were changed -#define kPrefChangeNotification @"prefChange" +#define kPrefChangeNotification @"prefChange" // Extras unload -#define kCPUMenuUnloadNotification @"cpuMenuUnload" -#define kDiskMenuUnloadNotification @"diskMenuUnload" -#define kMemMenuUnloadNotification @"memMenuUnload" -#define kNetMenuUnloadNotification @"netMenuUnload" +#define kCPUMenuUnloadNotification @"cpuMenuUnload" +#define kDiskMenuUnloadNotification @"diskMenuUnload" +#define kMemMenuUnloadNotification @"memMenuUnload" +#define kNetMenuUnloadNotification @"netMenuUnload" /////////////////////////////////////////////////////////////// // -// String formats +// String formats // /////////////////////////////////////////////////////////////// -#define kMenuIndentFormat @" %@" -#define kMenuDoubleIndentFormat @" %@" -#define kMenuTripleIndentFormat @" %@" +#define kMenuIndentFormat @" %@" +#define kMenuDoubleIndentFormat @" %@" +#define kMenuTripleIndentFormat @" %@" -#define kBorderAlpha 0.8f +#define kBorderAlpha 0.8 diff --git a/InfoPlistPreprocessor.h b/InfoPlistPreprocessor.h index 27169b6f..92160c94 100644 --- a/InfoPlistPreprocessor.h +++ b/InfoPlistPreprocessor.h @@ -9,7 +9,7 @@ #ifndef InfoPlistPreprocessor_h #define InfoPlistPreprocessor_h -#define MM_VERSION 2.1.5 +#define MM_VERSION 2.1.5 #define MM_COPYRIGHT MenuMeters MM_VERSION, by many contributors #endif /* InfoPlistPreprocessor_h */ diff --git a/LocalizedStrings.h b/LocalizedStrings.h index 37da779f..d23fa97d 100644 --- a/LocalizedStrings.h +++ b/LocalizedStrings.h @@ -5,15 +5,16 @@ // Created by Yuji on 12/7/20. // -#import #import +#import NS_ASSUME_NONNULL_BEGIN @interface LocalizedStrings : NSObject --(NSString*)objectForKey:(NSString*)key; + +- (NSString *)objectForKey:(NSString *)key; @end -extern LocalizedStrings*localizedStrings; +extern LocalizedStrings *localizedStrings; NS_ASSUME_NONNULL_END diff --git a/LocalizedStrings.m b/LocalizedStrings.m index 26168401..679a3925 100644 --- a/LocalizedStrings.m +++ b/LocalizedStrings.m @@ -6,14 +6,15 @@ // #import "LocalizedStrings.h" -LocalizedStrings*localizedStrings; +LocalizedStrings *localizedStrings; @implementation LocalizedStrings --(NSString*)objectForKey:(NSString*)key -{ - return [[NSBundle mainBundle] localizedStringForKey:key value:nil table:nil]; + +- (NSString *)objectForKey:(NSString *)key { + return [[NSBundle mainBundle] localizedStringForKey:key value:nil table:nil]; } -+(void)load -{ - localizedStrings=[[LocalizedStrings alloc] init]; + ++ (void)load { + localizedStrings = [[LocalizedStrings alloc] init]; } + @end diff --git a/MenuExtras/MenuMeterCPU/MenuMeterCPUExtra.h b/MenuExtras/MenuMeterCPU/MenuMeterCPUExtra.h index 7dc5dd15..24482dfc 100644 --- a/MenuExtras/MenuMeterCPU/MenuMeterCPUExtra.h +++ b/MenuExtras/MenuMeterCPU/MenuMeterCPUExtra.h @@ -1,61 +1,60 @@ // // MenuMeterCPUExtra.h // -// Menu Extra implementation +// Menu Extra implementation // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -#import -#import -#import "MenuMeters.h" -#import "MenuMeterDefaults.h" #import "MenuMeterCPU.h" #import "MenuMeterCPUStats.h" #import "MenuMeterCPUTopProcesses.h" -#import "MenuMeterUptime.h" +#import "MenuMeterDefaults.h" #import "MenuMeterPowerMate.h" +#import "MenuMeterUptime.h" #import "MenuMeterWorkarounds.h" - +#import "MenuMeters.h" +#import +#import @interface MenuMeterCPUExtra : NSMenuExtra { // Menu Extra necessities - NSMenu *extraMenu; + NSMenu *extraMenu; // Prefs object - MenuMeterDefaults *ourPrefs; + MenuMeterDefaults *ourPrefs; // Info gatherers - MenuMeterCPUStats *cpuInfo; - MenuMeterCPUTopProcesses *cpuTopProcesses; - MenuMeterUptime *uptimeInfo; + MenuMeterCPUStats *cpuInfo; + MenuMeterCPUTopProcesses *cpuTopProcesses; + MenuMeterUptime *uptimeInfo; // PowerMate support - MenuMeterPowerMate *powerMate; + MenuMeterPowerMate *powerMate; // The length of the menu item - float menuWidth; + float menuWidth; // Prerendered percentage text displays and their calculated width - float percentWidth; + float percentWidth; // Historical data samples - NSMutableArray *loadHistory; + NSMutableArray *loadHistory; // Cached colors and theme support - NSColor *userColor, - *systemColor, - *fgMenuThemeColor, - *temperatureColor; + NSColor *userColor, + *systemColor, + *fgMenuThemeColor, + *temperatureColor; } // MenuMeterCPUExtra diff --git a/MenuExtras/MenuMeterCPU/MenuMeterCPUExtra.m b/MenuExtras/MenuMeterCPU/MenuMeterCPUExtra.m index 5f40334f..c734dd07 100644 --- a/MenuExtras/MenuMeterCPU/MenuMeterCPUExtra.m +++ b/MenuExtras/MenuMeterCPU/MenuMeterCPUExtra.m @@ -1,95 +1,106 @@ // // MenuMeterCPUExtra.m // -// Menu Extra implementation +// Menu Extra implementation // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #import "MenuMeterCPUExtra.h" /////////////////////////////////////////////////////////////// // -// Private methods +// Private methods // /////////////////////////////////////////////////////////////// @interface MenuMeterCPUExtra (PrivateMethods) // Image renderers -- (void)renderHistoryGraphIntoImage:(NSImage *)image forProcessor:(uint32_t)processor atOffset:(float)offset; -- (void)renderSinglePercentIntoImage:(NSImage *)image forProcessor:(uint32_t)processor atOffset:(float)offset; -- (void)renderSplitPercentIntoImage:(NSImage *)image forProcessor:(uint32_t)processor atOffset:(float)offset; -- (void)renderThermometerIntoImage:(NSImage *)image forProcessor:(uint32_t)processor atOffset:(float)offset; -- (void)renderHorizontalThermometerIntoImage:(NSImage *)image forProcessor:(uint32_t)processor atX:(float)x andY:(float)y withWidth:(float)width andHeight:(float)height; + +- (void)renderHistoryGraphImageSize:(NSSize)imageSize forProcessor:(uint32_t)processor atOffset:(float)offset; + +- (void)renderSinglePercentImageSize:(NSSize)imageSize forProcessor:(uint32_t)processor atOffset:(float)offset; + +- (void)renderSplitPercentImageSize:(NSSize)imageSize forProcessor:(uint32_t)processor atOffset:(float)offset; + +- (void)renderThermometerImageSize:(NSSize)imageSize forProcessor:(uint32_t)processor atOffset:(float)offset; + +- (void)renderHorizontalThermometerImageSize:(NSSize)imageSize forProcessor:(uint32_t)processor atX:(float)x andY:(float)y withWidth:(float)width andHeight:(float)height; // Timer callbacks + - (void)updateMenuWhenDown; + - (void)updatePowerMate; // Menu actions + - (void)openProcessViewer:(id)sender; + - (void)openActivityMonitor:(id)sender; + - (void)openConsole:(id)sender; // Prefs + - (void)configFromPrefs:(NSNotification *)notification; // Utilities + - (void)getCPULoadForCPU:(uint32_t)processor - atPosition:(NSInteger)position - returnSystem:(double *)system - returnUser:(double *)user; + atPosition:(NSInteger)position + returnSystem:(double *)system + returnUser:(double *)user; @end - /////////////////////////////////////////////////////////////// // -// Localized strings +// Localized strings // /////////////////////////////////////////////////////////////// -#define kSingleProcessorTitle @"Processor:" -#define kMultiProcessorTitle @"Processors:" -#define kUptimeTitle @"Uptime:" -#define kTaskThreadTitle @"Tasks/Threads:" -#define kLoadAverageTitle @"Load Average (1m, 5m, 15m):" -#define kProcessTitle @"Top CPU Intensive Processes:" -#define kOpenProcessViewerTitle @"Open Process Viewer" -#define kOpenConsoleTitle @"Open Console" -#define kNoInfoErrorMessage @"No info available" +#define kSingleProcessorTitle @"Processor:" +#define kMultiProcessorTitle @"Processors:" +#define kUptimeTitle @"Uptime:" +#define kTaskThreadTitle @"Tasks/Threads:" +#define kLoadAverageTitle @"Load Average (1m, 5m, 15m):" +#define kProcessTitle @"Top CPU Intensive Processes:" +#define kOpenProcessViewerTitle @"Open Process Viewer" +#define kOpenConsoleTitle @"Open Console" +#define kNoInfoErrorMessage @"No info available" #define kCPUPowerLimitStatusTitle @"CPU power limit:" /////////////////////////////////////////////////////////////// // -// init/unload/dealloc +// init/unload/dealloc // /////////////////////////////////////////////////////////////// -@implementation MenuMeterCPUExtra -{ - float cpuTemperatureDisplayWidth; +@implementation MenuMeterCPUExtra { + float cpuTemperatureDisplayWidth; } -- init { + +- (instancetype)init { self = [super initWithBundleID:kCPUMenuBundleID]; - NSBundle*bundle=[NSBundle mainBundle]; + NSBundle *bundle = [NSBundle mainBundle]; if (!self) { return nil; } @@ -97,7 +108,7 @@ @implementation MenuMeterCPUExtra // Load our pref bundle, we do this as a bundle because we are a plugin // to SystemUIServer and as a result cannot have the same class loaded // from every meter. Using a shared bundle each loads fixes this. - ourPrefs = [MenuMeterDefaults sharedMenuMeterDefaults]; + ourPrefs = [MenuMeterDefaults sharedMenuMeterDefaults]; if (!ourPrefs) { NSLog(@"MenuMeterCPU unable to connect to preferences. Abort."); return nil; @@ -105,7 +116,7 @@ @implementation MenuMeterCPUExtra // Data gatherers and storage cpuInfo = [[MenuMeterCPUStats alloc] init]; - cpuTopProcesses = [[MenuMeterCPUTopProcesses alloc] init]; + cpuTopProcesses = [[MenuMeterCPUTopProcesses alloc] init]; uptimeInfo = [[MenuMeterUptime alloc] init]; loadHistory = [NSMutableArray array]; if (!(cpuInfo && uptimeInfo && loadHistory && cpuTopProcesses)) { @@ -125,11 +136,12 @@ @implementation MenuMeterCPUExtra NSMenuItem *menuItem = nil; // Add processor info which never changes - if ([cpuInfo numberOfCPUs] != 1) { + if ([cpuInfo numberOfCPUs] != 1) { menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:[bundle localizedStringForKey:kMultiProcessorTitle value:nil table:nil] action:nil keyEquivalent:@""]; - } else { + } + else { menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:[bundle localizedStringForKey:kSingleProcessorTitle value:nil table:nil] action:nil keyEquivalent:@""]; @@ -139,10 +151,10 @@ @implementation MenuMeterCPUExtra action:nil keyEquivalent:@""]; [menuItem setEnabled:NO]; - menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuIndentFormat, [cpuInfo coreDescription]] - action:nil - keyEquivalent:@""]; - [menuItem setEnabled:NO]; + menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuIndentFormat, [cpuInfo coreDescription]] + action:nil + keyEquivalent:@""]; + [menuItem setEnabled:NO]; // Add uptime title and blank for uptime display menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:[bundle localizedStringForKey:kUptimeTitle value:nil table:nil] @@ -168,26 +180,25 @@ @implementation MenuMeterCPUExtra menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:@"" action:nil keyEquivalent:@""]; [menuItem setEnabled:NO]; - menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:[bundle localizedStringForKey:kCPUPowerLimitStatusTitle value:nil table:nil] - action:nil - keyEquivalent:@""]; - [menuItem setEnabled:NO]; - menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:@"" action:nil keyEquivalent:@""]; - [menuItem setEnabled:NO]; - - - // Add top kCPUrocessCountMax most CPU intensive processes - menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:[bundle localizedStringForKey:kProcessTitle value:nil table:nil] - action:nil - keyEquivalent:@""]; - [menuItem setEnabled:NO]; - - // as this list is "static" unfortunately we need all of the kCPUrocessCountMax menu items and hide/show later the un-wanted/wanted ones - for (NSInteger ndx = 0; ndx < kCPUrocessCountMax; ++ndx) { - menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:@"" action:nil keyEquivalent:@""]; - [menuItem setEnabled:NO]; - } - + menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:[bundle localizedStringForKey:kCPUPowerLimitStatusTitle value:nil table:nil] + action:nil + keyEquivalent:@""]; + [menuItem setEnabled:NO]; + menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:@"" action:nil keyEquivalent:@""]; + [menuItem setEnabled:NO]; + + // Add top kCPUrocessCountMax most CPU intensive processes + menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:[bundle localizedStringForKey:kProcessTitle value:nil table:nil] + action:nil + keyEquivalent:@""]; + [menuItem setEnabled:NO]; + + // as this list is "static" unfortunately we need all of the kCPUrocessCountMax menu items and hide/show later the un-wanted/wanted ones + for (NSInteger ndx = 0; ndx < kCPUrocessCountMax; ++ndx) { + menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:@"" action:nil keyEquivalent:@""]; + [menuItem setEnabled:NO]; + } + // And the "Open Process Viewer"/"Open Activity Monitor" and "Open Console" item [extraMenu addItem:[NSMenuItem separatorItem]]; menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:[bundle localizedStringForKey:kOpenConsoleTitle value:nil table:nil] @@ -197,110 +208,119 @@ @implementation MenuMeterCPUExtra [self addStandardMenuEntriesTo:extraMenu]; // Get our view - - // And configure directly from prefs on first load [self configFromPrefs:nil]; // And hand ourself back to SystemUIServer - NSLog(@"MenuMeterCPU loaded."); + MMLog(@"MenuMeterCPU loaded."); return self; } // initWithBundle - // dealloc +// dealloc /////////////////////////////////////////////////////////////// // -// NSMenuExtraView callbacks +// NSMenuExtraView callbacks // /////////////////////////////////////////////////////////////// - (NSImage *)image { - [self setupAppearance]; - // Image to render into (and return to view) - NSImage *currentImage = [[NSImage alloc] initWithSize:NSMakeSize((float)menuWidth, - self.height-1)]; - if (!currentImage) return nil; // Don't render without data - if (![loadHistory count]) return nil; - - - uint32_t cpuCount=[cpuInfo numberOfCPUs]; - uint32_t stride=[ourPrefs cpuAvgLowerHalfProcs]?[cpuInfo numberOfCPUs]/[cpuInfo numberOfCores]:1; - float renderOffset = 0.0f; - // Horizontal CPU thermometer is handled differently because it has to - // manage rows and columns in a very different way from normal horizontal - // layout - if(![ourPrefs cpuShowTemperature] && [ourPrefs cpuDisplayMode]==0){ - [currentImage lockFocus]; - NSAttributedString *cpuString = [[NSAttributedString alloc] - initWithString:@"CPU" - attributes:[NSDictionary dictionaryWithObjectsAndKeys:[NSFont monospacedDigitSystemFontOfSize:[NSFont smallSystemFontSize] weight:NSFontWeightRegular], - NSFontAttributeName, fgMenuThemeColor, NSForegroundColorAttributeName, - nil]]; - [cpuString drawAtPoint:NSMakePoint( - kCPULabelOnlyWidth - (float)round([cpuString size].width) - 1, - (float)(([currentImage size].height-[cpuString size].height) / 2)+self.baselineOffset - )]; - [currentImage unlockFocus]; - return currentImage; - } - if ([ourPrefs cpuShowTemperature]) { - [self renderSingleTemperatureIntoImage:currentImage atOffset:renderOffset]; - renderOffset += cpuTemperatureDisplayWidth; - } - if ([ourPrefs cpuDisplayMode] & kCPUDisplayHorizontalThermometer) { - // Calculate the minimum number of columns that will be needed - uint32_t rowCount = [ourPrefs cpuHorizontalRows]; - //ceil(A/B) for ints is equal (A+B-1)/B - uint32_t columnCount = (cpuCount+rowCount-1)/rowCount; - //((cpuCount - 1) / [ourPrefs cpuHorizontalRows]) + 1; - // Calculate a column width - float columnWidth = (menuWidth - 1.0f) / columnCount; - // Image height - float imageHeight = (float) ([currentImage size].height); - // Calculate a thermometer height - float thermometerHeight = ((imageHeight - 2) / rowCount); - for (uint32_t cpuNum = 0; cpuNum < cpuCount; cpuNum+=stride) { - float xOffset = renderOffset + ((cpuNum / rowCount) * columnWidth) + 1.0f; - float yOffset = (imageHeight - - (((cpuNum % rowCount) + 1) * thermometerHeight)) - 1.0f; - [self renderHorizontalThermometerIntoImage:currentImage forProcessor:cpuNum atX:xOffset andY:yOffset withWidth:columnWidth andHeight:thermometerHeight]; - } - } - else { - // Loop by processor - int cpuDisplayModePrefs = [ourPrefs cpuDisplayMode]; - for (uint32_t cpuNum = 0; cpuNum < cpuCount; cpuNum+=stride) { - - // Render graph if needed - if (cpuDisplayModePrefs & kCPUDisplayGraph) { - [self renderHistoryGraphIntoImage:currentImage forProcessor:cpuNum atOffset:renderOffset]; - // Adjust render offset - renderOffset += [ourPrefs cpuGraphLength]; + if (![loadHistory count]) + return nil; + + [self setupAppearance]; + + NSSize imageSize = NSMakeSize(menuWidth, self.height - 1); + + uint32_t cpuCount = [cpuInfo numberOfCPUs]; + uint32_t stride = [ourPrefs cpuAvgLowerHalfProcs] ? [cpuInfo numberOfCPUs] / [cpuInfo numberOfCores] : 1; + BOOL cpuShowTemperature = [ourPrefs cpuShowTemperature]; + int cpuDisplayMode = [ourPrefs cpuDisplayMode]; + MenuMeterDefaults *prefs = ourPrefs; + // Image to render into (and return to view) + NSImage *currentImage = [NSImage imageWithSize:imageSize + flipped:NO + drawingHandler:^BOOL(NSRect dstRect) { + // Horizontal CPU thermometer is handled differently because it has to + // manage rows and columns in a very different way from normal horizontal + // layout + float renderOffset = 0.0; + if (!cpuShowTemperature && cpuDisplayMode == 0) { + NSDictionary *attributes = @{ + NSFontAttributeName: [NSFont monospacedDigitSystemFontOfSize:[NSFont smallSystemFontSize] weight:NSFontWeightRegular], + NSForegroundColorAttributeName: self->fgMenuThemeColor + }; + NSAttributedString *cpuString = [[NSAttributedString alloc] + initWithString:@"CPU" + attributes:attributes]; + NSPoint pos = NSMakePoint( + kCPULabelOnlyWidth - round([cpuString size].width) - 1, + ((imageSize.height - [cpuString size].height) / 2) + self.baselineOffset); + [cpuString drawAtPoint:pos]; + return YES; + } + if (cpuShowTemperature) { + [self renderSingleTemperatureImageSize:imageSize atOffset:renderOffset]; + renderOffset += self->cpuTemperatureDisplayWidth; + } + if (cpuDisplayMode & kCPUDisplayHorizontalThermometer) { + // Calculate the minimum number of columns that will be needed + uint32_t rowCount = [prefs cpuHorizontalRows]; + // ceil(A/B) for ints is equal (A+B-1)/B + uint32_t columnCount = (cpuCount + rowCount - 1) / rowCount; + //((cpuCount - 1) / [prefs cpuHorizontalRows]) + 1; + // Calculate a column width + float columnWidth = (self->menuWidth - 1.0) / columnCount; + // Image height + float imageHeight = (float)imageSize.height; + // Calculate a thermometer height + float thermometerHeight = ((imageHeight - 2) / rowCount); + for (uint32_t cpuNum = 0; cpuNum < cpuCount; cpuNum += stride) { + float xOffset = renderOffset + ((cpuNum / rowCount) * columnWidth) + 1.0; + float yOffset = (imageHeight - + ((cpuNum % rowCount) + 1) * thermometerHeight) - + 1.0; + [self renderHorizontalThermometerImageSize:imageSize forProcessor:cpuNum atX:xOffset andY:yOffset withWidth:columnWidth andHeight:thermometerHeight]; } - // Render percent if needed - if (cpuDisplayModePrefs & kCPUDisplayPercent) { - if ([ourPrefs cpuPercentDisplay] == kCPUPercentDisplaySplit) { - [self renderSplitPercentIntoImage:currentImage forProcessor:cpuNum atOffset:renderOffset]; - } else { - [self renderSinglePercentIntoImage:currentImage forProcessor:cpuNum atOffset:renderOffset]; + } + else { + // Loop by processor + int cpuDisplayModePrefs = [prefs cpuDisplayMode]; + for (uint32_t cpuNum = 0; cpuNum < cpuCount; cpuNum += stride) { + + // Render graph if needed + if (cpuDisplayModePrefs & kCPUDisplayGraph) { + [self renderHistoryGraphImageSize:imageSize forProcessor:cpuNum atOffset:renderOffset]; + // Adjust render offset + renderOffset += [prefs cpuGraphLength]; } - renderOffset += percentWidth; - } - if (cpuDisplayModePrefs & kCPUDisplayThermometer) { - [self renderThermometerIntoImage:currentImage forProcessor:cpuNum atOffset:renderOffset]; - renderOffset += kCPUThermometerDisplayWidth; - } - // At end of each proc adjust spacing - renderOffset += kCPUDisplayMultiProcGapWidth; + // Render percent if needed + if (cpuDisplayModePrefs & kCPUDisplayPercent) { + if ([prefs cpuPercentDisplay] == kCPUPercentDisplaySplit) { + [self renderSplitPercentImageSize:imageSize forProcessor:cpuNum atOffset:renderOffset]; + } + else { + [self renderSinglePercentImageSize:imageSize forProcessor:cpuNum atOffset:renderOffset]; + } + renderOffset += self->percentWidth; + } + if (cpuDisplayModePrefs & kCPUDisplayThermometer) { + [self renderThermometerImageSize:imageSize forProcessor:cpuNum atOffset:renderOffset]; + renderOffset += kCPUThermometerDisplayWidth; + } + // At end of each proc adjust spacing + renderOffset += kCPUDisplayMultiProcGapWidth; - // If we're averaging all we're done on first iteration - if ([ourPrefs cpuAvgAllProcs]) break; + // If we're averaging all we're done on first iteration + if ([prefs cpuAvgAllProcs]) + break; + } } - } + return YES; + }]; // Send it back for the view to render return currentImage; @@ -311,51 +331,53 @@ - (NSMenu *)menu { // Update the various displays starting with uptime NSString *title = [NSString stringWithFormat:kMenuIndentFormat, [uptimeInfo uptime]]; - if (title) LiveUpdateMenuItemTitle(extraMenu, kCPUUptimeInfoMenuIndex, title); - + if (title) + LiveUpdateMenuItemTitle(extraMenu, kCPUUptimeInfoMenuIndex, title); + // Tasks title = [NSString stringWithFormat:kMenuIndentFormat, [cpuInfo currentProcessorTasks]]; - if (title) LiveUpdateMenuItemTitle(extraMenu, kCPUTaskInfoMenuIndex, title); - + if (title) + LiveUpdateMenuItemTitle(extraMenu, kCPUTaskInfoMenuIndex, title); + // Load title = [NSString stringWithFormat:kMenuIndentFormat, [cpuInfo loadAverage]]; - if (title) LiveUpdateMenuItemTitle(extraMenu, kCPULoadInfoMenuIndex, title); - - title = [NSString stringWithFormat:kMenuIndentFormat, [cpuInfo cpuPowerLimitStatus]]; - if (title) LiveUpdateMenuItemTitle(extraMenu, kCPUPowerLimitInfoMenuIndex, title); - - - // Top CPU intensive processes - NSArray* processes = ([ourPrefs cpuMaxProcessCount] > 0 ? [cpuTopProcesses runningProcessesByCPUUsage:[ourPrefs cpuMaxProcessCount]] : nil); - LiveUpdateMenuItemTitleAndVisibility(extraMenu, kCPUProcessLabelMenuIndex, nil, (processes == nil)); - for (NSInteger ndx = 0; ndx < kCPUrocessCountMax; ++ndx) { - if (ndx < processes.count) { - NSString*name=processes[ndx][kProcessListItemProcessNameKey]; - float percent=[processes[ndx][kProcessListItemCPUKey] floatValue]; - title = [NSString stringWithFormat:kMenuIndentFormat, [NSString stringWithFormat:@"%@ (%.1f%%)", name,percent ]]; - NSMenuItem*mi=[extraMenu itemAtIndex: kCPUProcessMenuIndex + ndx]; - mi.title=title; - mi.hidden=title.length==0; - - - NSNumber* pid=processes[ndx][kProcessListItemPIDKey]; - NSRunningApplication*app=[NSRunningApplication runningApplicationWithProcessIdentifier:pid.intValue]; - NSImage*icon=app.icon; - if(!icon){ - static NSImage*defaultIcon=nil; - if(!defaultIcon){ - defaultIcon=[[NSWorkspace sharedWorkspace] iconForFile:@"/bin/bash"]; - } - icon=defaultIcon; - } - icon.size=NSMakeSize(16, 16); - mi.image=icon; - } - else { - LiveUpdateMenuItemTitleAndVisibility(extraMenu, kCPUProcessMenuIndex + ndx, nil, YES); - } - } - + if (title) + LiveUpdateMenuItemTitle(extraMenu, kCPULoadInfoMenuIndex, title); + + title = [NSString stringWithFormat:kMenuIndentFormat, [cpuInfo cpuPowerLimitStatus]]; + if (title) + LiveUpdateMenuItemTitle(extraMenu, kCPUPowerLimitInfoMenuIndex, title); + + // Top CPU intensive processes + NSArray *processes = ([ourPrefs cpuMaxProcessCount] > 0 ? [cpuTopProcesses runningProcessesByCPUUsage:[ourPrefs cpuMaxProcessCount]] : nil); + LiveUpdateMenuItemTitleAndVisibility(extraMenu, kCPUProcessLabelMenuIndex, nil, (processes == nil)); + for (NSInteger ndx = 0; ndx < kCPUrocessCountMax; ++ndx) { + if (ndx < processes.count) { + NSString *name = processes[ndx][kProcessListItemProcessNameKey]; + float percent = [processes[ndx][kProcessListItemCPUKey] floatValue]; + title = [NSString stringWithFormat:kMenuIndentFormat, [NSString stringWithFormat:@"%@ (%.1f%%)", name, percent]]; + NSMenuItem *mi = [extraMenu itemAtIndex:kCPUProcessMenuIndex + ndx]; + mi.title = title; + mi.hidden = title.length == 0; + + NSNumber *pid = processes[ndx][kProcessListItemPIDKey]; + NSRunningApplication *app = [NSRunningApplication runningApplicationWithProcessIdentifier:pid.intValue]; + NSImage *icon = app.icon; + if (!icon) { + static NSImage *defaultIcon = nil; + if (!defaultIcon) { + defaultIcon = [[NSWorkspace sharedWorkspace] iconForFile:@"/bin/bash"]; + } + icon = defaultIcon; + } + icon.size = NSMakeSize(16, 16); + mi.image = icon; + } + else { + LiveUpdateMenuItemTitleAndVisibility(extraMenu, kCPUProcessMenuIndex + ndx, nil, YES); + } + } + // Send the menu back to SystemUIServer return extraMenu; @@ -363,60 +385,62 @@ - (NSMenu *)menu { /////////////////////////////////////////////////////////////// // -// NSMenuDelegate +// NSMenuDelegate // /////////////////////////////////////////////////////////////// - (void)menuWillOpen:(NSMenu *)menu { - - if ([ourPrefs cpuMaxProcessCount] > 0) - [cpuTopProcesses startUpdateProcessList]; - - [super menuWillOpen:menu]; - + + if ([ourPrefs cpuMaxProcessCount] > 0) + [cpuTopProcesses startUpdateProcessList]; + + [super menuWillOpen:menu]; + } // menuWillOpen: - (void)menuDidClose:(NSMenu *)menu { - [cpuTopProcesses stopUpdateProcessList]; + [cpuTopProcesses stopUpdateProcessList]; - [super menuDidClose:menu]; + [super menuDidClose:menu]; } // menuDidClose: /////////////////////////////////////////////////////////////// // -// Image renderers +// Image renderers // /////////////////////////////////////////////////////////////// -- (void)renderHistoryGraphIntoImage:(NSImage *)image forProcessor:(uint32_t)processor atOffset:(float)offset { +- (void)renderHistoryGraphImageSize:(NSSize)imageSize forProcessor:(uint32_t)processor atOffset:(float)offset { // Construct paths - NSBezierPath *systemPath = [NSBezierPath bezierPath]; - NSBezierPath *userPath = [NSBezierPath bezierPath]; - if (!(systemPath && userPath)) return; + NSBezierPath *systemPath = [NSBezierPath bezierPath]; + NSBezierPath *userPath = [NSBezierPath bezierPath]; + if (!(systemPath && userPath)) + return; // Position for initial offset [systemPath moveToPoint:NSMakePoint(offset, 0)]; [userPath moveToPoint:NSMakePoint(offset, 0)]; // Loop over pixels in desired width until we're out of data int renderPosition = 0; - float renderHeight = (float)[image size].height - 0.5f; // Save space for baseline + float renderHeight = (float)imageSize.height - 0.5; // Save space for baseline int cpuGraphLength = [ourPrefs cpuGraphLength]; for (renderPosition = 0; renderPosition < cpuGraphLength; renderPosition++) { // No data at this position? - if (renderPosition >= [loadHistory count]) break; + if (renderPosition >= [loadHistory count]) + break; // Grab data - double system=0, user=0; - [self getCPULoadForCPU:processor atPosition:renderPosition returnSystem:&system returnUser:&user]; + double system = 0, user = 0; + [self getCPULoadForCPU:processor atPosition:renderPosition returnSystem:&system returnUser:&user]; // Update paths (adding baseline) [userPath lineToPoint:NSMakePoint(offset + renderPosition, - (((system + user) > 1 ? 1 : (system + user)) * renderHeight) + 0.5f)]; + (((system + user) > 1 ? 1 : (system + user)) * renderHeight) + 0.5)]; [systemPath lineToPoint:NSMakePoint(offset + renderPosition, - (system * renderHeight) + 0.5f)]; + (system * renderHeight) + 0.5)]; } // Return to lower edge (fill will close the graph) @@ -424,195 +448,202 @@ - (void)renderHistoryGraphIntoImage:(NSImage *)image forProcessor:(uint32_t)proc [systemPath lineToPoint:NSMakePoint(offset + renderPosition - 1, 0)]; // Draw - [image lockFocus]; [userColor set]; [userPath fill]; [systemColor set]; [systemPath fill]; - // Clean up - [[NSColor blackColor] set]; - [image unlockFocus]; - -} // renderHistoryGraphIntoImage:forProcessor:atOffset: --(NSAttributedString*)percentStringForLoad:(float)load andColor:(NSColor*)color -{ - float fontSize = self.fontSize; - NSDictionary *textAttributes = [NSDictionary dictionaryWithObjectsAndKeys: - [NSFont monospacedDigitSystemFontOfSize:fontSize weight:NSFontWeightRegular], - NSFontAttributeName, - color, - NSForegroundColorAttributeName, - nil]; - NSAttributedString *cacheText = [[NSAttributedString alloc] - initWithString:[NSString stringWithFormat:@"%d%%", (int)roundf(load * 100.0f)] - attributes:textAttributes]; - return cacheText; +} // renderHistoryGraphImageSize:forProcessor:atOffset: + +- (NSAttributedString *)percentStringForLoad:(float)load andColor:(NSColor *)color { + float fontSize = self.fontSize; + if ([cpuInfo numberOfCPUs] > 8) { + fontSize -= 2; + } + NSFont *percentFont = [NSFont monospacedDigitSystemFontOfSize:fontSize weight:NSFontWeightRegular]; + NSFont *traitFont = [NSFontManager.sharedFontManager convertFont:percentFont toHaveTrait:NSCondensedFontMask]; + if (traitFont) { + percentFont = traitFont; + } + NSDictionary *textAttributes = [NSDictionary dictionaryWithObjectsAndKeys: + percentFont, + NSFontAttributeName, + color, + NSForegroundColorAttributeName, + nil]; + NSAttributedString *cacheText = [[NSAttributedString alloc] + initWithString:[NSString stringWithFormat:@"%d%%", (int)roundf(load * 100.0)] + attributes:textAttributes]; + return cacheText; } -- (void)renderSinglePercentIntoImage:(NSImage *)image forProcessor:(uint32_t)processor atOffset:(float)offset { - + +- (void)renderSinglePercentImageSize:(NSSize)imageSize forProcessor:(uint32_t)processor atOffset:(float)offset { // Current load (if available) - double system=0,user=0; - [self getCPULoadForCPU:processor atPosition:-1 returnSystem:&system returnUser:&user]; - float totalLoad = system + user; - if (totalLoad > 1) totalLoad = 1; - if (totalLoad < 0) totalLoad = 0; - if ([ourPrefs cpuSumAllProcsPercent]) { - totalLoad *= [cpuInfo numberOfCPUs]; - } - - - [image lockFocus]; - NSAttributedString*string=[self percentStringForLoad:totalLoad andColor:fgMenuThemeColor]; - [string drawAtPoint:NSMakePoint(offset + percentWidth - ceilf((float)[string size].width) - 1, - (float)(([image size].height - [string size].height) / 2)+self.baselineOffset)]; - [image unlockFocus]; - -} // renderSinglePercentIntoImage:forProcessor:atOffset: - -- (void)renderSplitPercentIntoImage:(NSImage *)image forProcessor:(uint32_t)processor atOffset:(float)offset { - - double system, user; - [self getCPULoadForCPU:processor atPosition:-1 returnSystem:&system returnUser:&user]; - if ((system < 0) || (user < 0)) { - return; - } - if ([ourPrefs cpuSumAllProcsPercent]) { - system *= [cpuInfo numberOfCPUs]; - user *= [cpuInfo numberOfCPUs]; - } + double system = 0, user = 0; + [self getCPULoadForCPU:processor atPosition:-1 returnSystem:&system returnUser:&user]; + float totalLoad = system + user; + if (totalLoad > 1) + totalLoad = 1; + if (totalLoad < 0) + totalLoad = 0; + if ([ourPrefs cpuSumAllProcsPercent]) { + totalLoad *= [cpuInfo numberOfCPUs]; + } + + NSAttributedString *string = [self percentStringForLoad:totalLoad andColor:fgMenuThemeColor]; + NSPoint pos = NSMakePoint(offset + percentWidth - ceil([string size].width) - 1, + ((imageSize.height - [string size].height) / 2) + self.baselineOffset); + [string drawAtPoint:pos]; + +} // renderSinglePercentImageSize:forProcessor:atOffset: + +- (void)renderSplitPercentImageSize:(NSSize)imageSize forProcessor:(uint32_t)processor atOffset:(float)offset { + + double system = 0, user = 0; + [self getCPULoadForCPU:processor atPosition:-1 returnSystem:&system returnUser:&user]; + if ((system < 0) || (user < 0)) { + return; + } + if ([ourPrefs cpuSumAllProcsPercent]) { + system *= [cpuInfo numberOfCPUs]; + user *= [cpuInfo numberOfCPUs]; + } // Get the prerendered text and draw - NSAttributedString *systemString = [self percentStringForLoad:system andColor:systemColor]; - NSAttributedString *userString = [self percentStringForLoad:user andColor:userColor]; - [image lockFocus]; - [systemString drawAtPoint:NSMakePoint(offset + percentWidth - [systemString size].width - 1, -1)]; - [userString drawAtPoint:NSMakePoint(offset + percentWidth - (float)[userString size].width - 1, - (float)floor([image size].height / 2)-1)]; - [image unlockFocus]; + NSAttributedString *systemString = [self percentStringForLoad:system andColor:systemColor]; + NSAttributedString *userString = [self percentStringForLoad:user andColor:userColor]; + [systemString drawAtPoint:NSMakePoint(offset + percentWidth - [systemString size].width - 1, -1)]; + [userString drawAtPoint:NSMakePoint(offset + percentWidth - [userString size].width - 1, + floor(imageSize.height / 2) - 1)]; } // renderSplitPercentIntoImage:forProcessor:atOffset: --(NSAttributedString*)renderTemperatureStringForString:(NSString*)temperatureString -{ - return [[NSAttributedString alloc] - initWithString:temperatureString - attributes:[NSDictionary dictionaryWithObjectsAndKeys: [NSFont monospacedDigitSystemFontOfSize:self.fontSize weight:NSFontWeightRegular], - NSFontAttributeName, temperatureColor, NSForegroundColorAttributeName, - nil]]; +- (NSAttributedString *)renderTemperatureStringForString:(NSString *)temperatureString { + NSFont *temperatureFont = [NSFont monospacedDigitSystemFontOfSize:self.fontSize weight:NSFontWeightRegular]; + NSFont *traitFont = [NSFontManager.sharedFontManager convertFont:temperatureFont toHaveTrait:NSCondensedFontMask]; + if (traitFont) { + temperatureFont = traitFont; + } + NSDictionary *attributes = @{ + NSFontAttributeName: temperatureFont, + NSForegroundColorAttributeName: temperatureColor + }; + return [[NSAttributedString alloc] initWithString:temperatureString + attributes:attributes]; } -- (void)renderSingleTemperatureIntoImage:(NSImage *)image atOffset:(float)offset { - float_t celsius = [cpuInfo cpuProximityTemperature]; - float_t fahrenheit=celsius*1.8+32; - NSString*temperatureString=@""; - switch([ourPrefs cpuTemperatureUnit]){ - case kCPUTemperatureUnitCelsius: - temperatureString=[NSString stringWithFormat:@"%.1f℃", celsius]; - if(celsius<-100){ - temperatureString=@"??℃"; - } - break; - case kCPUTemperatureUnitFahrenheit: - if(fahrenheit>=100){ - temperatureString=[NSString stringWithFormat:@"%d℉", (int)fahrenheit]; - }else{ - temperatureString=[NSString stringWithFormat:@"%.1f℉", fahrenheit]; - } - if(celsius<-100){ - temperatureString=@"??℉"; - } - break; - default: - temperatureString=@"???"; - } - [image lockFocus]; - NSAttributedString *renderTemperatureString =[self renderTemperatureStringForString:temperatureString]; - [renderTemperatureString drawAtPoint:NSMakePoint( - cpuTemperatureDisplayWidth - (float)round([renderTemperatureString size].width) - 1, - (float)(([image size].height-[renderTemperatureString size].height) / 2+self.baselineOffset) - )]; - [image unlockFocus]; -} // renderSingleTemperatureIntoImage:atOffset: +- (void)renderSingleTemperatureImageSize:(NSSize)imageSize atOffset:(float)offset { + float_t celsius = [cpuInfo cpuProximityTemperature]; + float_t fahrenheit = celsius * 1.8 + 32; + NSString *temperatureString = @""; + switch ([ourPrefs cpuTemperatureUnit]) { + case kCPUTemperatureUnitCelsius: + if (celsius > -100) { + temperatureString = [NSString stringWithFormat:@"%d℃", (int)round(celsius)]; + } + else { + temperatureString = @"??℃"; + } + break; + case kCPUTemperatureUnitFahrenheit: + if (fahrenheit >= 100) { + temperatureString = [NSString stringWithFormat:@"%d℉", (int)fahrenheit]; + } + else { + temperatureString = [NSString stringWithFormat:@"%.1f℉", fahrenheit]; + } + if (celsius < -100) { + temperatureString = @"??℉"; + } + break; + default: + temperatureString = @"???"; + } -- (void)renderThermometerIntoImage:(NSImage *)image forProcessor:(uint32_t)processor atOffset:(float)offset { + NSAttributedString *renderTemperatureString = [self renderTemperatureStringForString:temperatureString]; + NSPoint pos = NSMakePoint( + cpuTemperatureDisplayWidth - round([renderTemperatureString size].width) - 3, + ((imageSize.height - [renderTemperatureString size].height) / 2 + self.baselineOffset)); + [renderTemperatureString drawAtPoint:pos]; +} // renderSingleTemperatureIntoImage:atOffset: + +- (void)renderThermometerImageSize:(NSSize)imageSize forProcessor:(uint32_t)processor atOffset:(float)offset { - double system, user; - [self getCPULoadForCPU:processor atPosition:-1 returnSystem:&system returnUser:&user]; - if ((system < 0) || (user < 0)) { - return; - } + double system = 0, user = 0; + [self getCPULoadForCPU:processor atPosition:-1 returnSystem:&system returnUser:&user]; + if ((system < 0) || (user < 0)) { + return; + } // Paths - float thermometerTotalHeight = (float)[image size].height - 3.0f; - NSBezierPath *userPath = [NSBezierPath bezierPathWithRect:NSMakeRect(offset + 1.5f, 1.5f, kCPUThermometerDisplayWidth - 3, - thermometerTotalHeight * ((user + system) > 1 ? 1 : (user + system)))]; - NSBezierPath *systemPath = [NSBezierPath bezierPathWithRect:NSMakeRect(offset + 1.5f, 1.5f, kCPUThermometerDisplayWidth - 3, - thermometerTotalHeight * system)]; - NSBezierPath *framePath = [NSBezierPath bezierPathWithRect:NSMakeRect(offset + 1.5f, 1.5f, kCPUThermometerDisplayWidth - 3, thermometerTotalHeight)]; + NSRect thermometerFrame = NSMakeRect(offset, 0, kCPUThermometerDisplayWidth, imageSize.height); + NSRect userRect = thermometerFrame; + userRect.size.height *= (user + system) > 1 ? 1 : (user + system); + NSRect systemRect = thermometerFrame; + systemRect.size.height *= system; + + NSBezierPath *userPath = [NSBezierPath bezierPathWithRect:userRect]; + NSBezierPath *systemPath = [NSBezierPath bezierPathWithRect:systemRect]; // Draw - [image lockFocus]; - [userColor set]; + NSBezierPath *framePath = [NSBezierPath bezierPathWithRoundedRect:thermometerFrame xRadius:2 yRadius:2]; + [NSGraphicsContext saveGraphicsState]; + [framePath addClip]; + [[fgMenuThemeColor colorWithAlphaComponent:0.2] setFill]; + [framePath fill]; + + [userColor setFill]; [userPath fill]; - [systemColor set]; - [systemPath fill]; - [[fgMenuThemeColor colorWithAlphaComponent:kBorderAlpha] set]; - [framePath stroke]; - // Reset - [[NSColor blackColor] set]; - [image unlockFocus]; + [systemColor setFill]; + [systemPath fill]; + [NSGraphicsContext restoreGraphicsState]; } // renderThermometerIntoImage:forProcessor:atOffset: -- (void)renderHorizontalThermometerIntoImage:(NSImage *)image forProcessor:(uint32_t)processor atX:(float)x andY:(float)y withWidth:(float)width andHeight:(float)height { - double system, user; - [self getCPULoadForCPU:processor atPosition:-1 returnSystem:&system returnUser:&user]; - if ((system < 0) || (user < 0)) { - return; - } +- (void)renderHorizontalThermometerImageSize:(NSSize)imageSize forProcessor:(uint32_t)processor atX:(float)x andY:(float)y withWidth:(float)width andHeight:(float)height { + double system = 0, user = 0; + [self getCPULoadForCPU:processor atPosition:-1 returnSystem:&system returnUser:&user]; + if ((system < 0) || (user < 0)) { + return; + } // Paths - NSBezierPath *rightCapPath = [NSBezierPath bezierPathWithRect:NSMakeRect((x + width) - 2.0f, y, 1.0f, height - 1.0f)]; + NSBezierPath *rightCapPath = [NSBezierPath bezierPathWithRect:NSMakeRect((x + width) - 2.0, y, 1.0, height - 1.0)]; - NSBezierPath *userPath = [NSBezierPath bezierPathWithRect:NSMakeRect(x + 1.0f, y, (width - 2.0f) * ((user + system) > 1 ? 1 : (user + system)), height - 1.0f)]; + NSBezierPath *userPath = [NSBezierPath bezierPathWithRect:NSMakeRect(x + 1.0, y, (width - 2.0) * ((user + system) > 1 ? 1 : (user + system)), height - 1.0)]; - NSBezierPath *systemPath = [NSBezierPath bezierPathWithRect:NSMakeRect(x + 1.0f, y, (width - 2.0f) * system, height - 1.0f)]; + NSBezierPath *systemPath = [NSBezierPath bezierPathWithRect:NSMakeRect(x + 1.0, y, (width - 2.0) * system, height - 1.0)]; // Draw - [image lockFocus]; [userColor set]; [userPath fill]; [systemColor set]; [systemPath fill]; - [[fgMenuThemeColor colorWithAlphaComponent:kBorderAlpha] set]; - [rightCapPath fill]; - - // Reset - [[NSColor blackColor] set]; - [image unlockFocus]; - -} // renderHorizontalThermometerIntoImage:forProcessor:atX:andY:withWidth:andHeight: + [[fgMenuThemeColor colorWithAlphaComponent:kBorderAlpha] set]; + [rightCapPath fill]; +} // renderHorizontalThermometerImageSize:forProcessor:atX:andY:withWidth:andHeight: /////////////////////////////////////////////////////////////// // -// Timer callbacks +// Timer callbacks // /////////////////////////////////////////////////////////////// - (void)timerFired:(NSTimer *)timerFired { // Get the current load NSArray *currentLoad = [cpuInfo currentLoadBySorting:[ourPrefs cpuSortByUsage]]; - if (!currentLoad) return; + if (!currentLoad) + return; // Add to history (at least one) if ([ourPrefs cpuDisplayMode] & kCPUDisplayGraph) { if ([loadHistory count] >= [ourPrefs cpuGraphLength]) { [loadHistory removeObjectsInRange:NSMakeRange(0, [loadHistory count] - [ourPrefs cpuGraphLength] + 1)]; } - } else { + } + else { [loadHistory removeAllObjects]; } [loadHistory addObject:currentLoad]; @@ -641,11 +672,12 @@ - (void)updateMenuWhenDown { - (void)updatePowerMate { - int numberOfCPUs = [cpuInfo numberOfCPUs]; + int numberOfCPUs = [cpuInfo numberOfCPUs]; // Current load (if available) NSArray *currentLoad = [loadHistory lastObject]; - if (!currentLoad || ([currentLoad count] < numberOfCPUs)) return; + if (!currentLoad || ([currentLoad count] < numberOfCPUs)) + return; double totalLoad = 0; for (uint32_t cpuNum = 0; cpuNum < numberOfCPUs; cpuNum++) { @@ -653,17 +685,22 @@ - (void)updatePowerMate { totalLoad += load.system + load.user; } totalLoad /= numberOfCPUs; - if (totalLoad > 1) totalLoad = 1; - if (totalLoad < 0) totalLoad = 0; + if (totalLoad > 1) + totalLoad = 1; + if (totalLoad < 0) + totalLoad = 0; if ([ourPrefs cpuPowerMateMode] == kCPUPowerMateGlow) { // Ramp to the glow point in half our update time [powerMate setGlow:totalLoad rampInterval:[ourPrefs cpuInterval] / 2]; - } else if ([ourPrefs cpuPowerMateMode] == kCPUPowerMatePulse) { + } + else if ([ourPrefs cpuPowerMateMode] == kCPUPowerMatePulse) { [powerMate setPulse:totalLoad]; - } else if ([ourPrefs cpuPowerMateMode] == kCPUPowerMateInverseGlow) { + } + else if ([ourPrefs cpuPowerMateMode] == kCPUPowerMateInverseGlow) { [powerMate setGlow:(1.0 - totalLoad) rampInterval:[ourPrefs cpuInterval] / 2]; - } else if ([ourPrefs cpuPowerMateMode] == kCPUPowerMateInversePulse) { + } + else if ([ourPrefs cpuPowerMateMode] == kCPUPowerMateInversePulse) { [powerMate setPulse:(1.0 - totalLoad)]; } @@ -671,7 +708,7 @@ - (void)updatePowerMate { /////////////////////////////////////////////////////////////// // -// Menu actions +// Menu actions // /////////////////////////////////////////////////////////////// @@ -683,7 +720,6 @@ - (void)openProcessViewer:(id)sender { } // openProcessViewer - - (void)openConsole:(id)sender { if (![[NSWorkspace sharedWorkspace] launchApplication:@"Console.app"]) { @@ -694,81 +730,82 @@ - (void)openConsole:(id)sender { /////////////////////////////////////////////////////////////// // -// Prefs +// Prefs // /////////////////////////////////////////////////////////////// --(float)baselineOffset -{ - float offset=1.0f; - if ([ourPrefs cpuPercentDisplay] == kCPUPercentDisplaySmall) { - offset=+0.5f; - } - if([ourPrefs cpuPercentDisplay] == kCPUPercentDisplaySplit){ - offset = +0.0f; - } - return offset; + +- (float)baselineOffset { + float offset = 0.0; + if ([ourPrefs cpuPercentDisplay] == kCPUPercentDisplaySmall) { + offset = 0.5; + } + if ([ourPrefs cpuPercentDisplay] == kCPUPercentDisplaySplit) { + offset = 0.0; + } + return offset; } --(float)fontSize -{ - float fontSize=14; - if ([ourPrefs cpuPercentDisplay] == kCPUPercentDisplaySmall) { - fontSize = 11; - } - if([ourPrefs cpuPercentDisplay] == kCPUPercentDisplaySplit){ - fontSize = 9.5f; - } - return fontSize; + +- (float)fontSize { + float fontSize = 14.0; + if ([ourPrefs cpuPercentDisplay] == kCPUPercentDisplaySmall) { + fontSize = 11.0; + } + if ([ourPrefs cpuPercentDisplay] == kCPUPercentDisplaySplit) { + fontSize = 9.5; + } + return fontSize; } + - (void)configFromPrefs:(NSNotification *)notification { #ifdef ELCAPITAN - [super configDisplay:kCPUMenuBundleID fromPrefs:ourPrefs withTimerInterval:[ourPrefs cpuInterval]]; + [super configDisplay:kCPUMenuBundleID + fromPrefs:ourPrefs + withTimerInterval:[ourPrefs cpuInterval]]; #endif - // Update prefs - [ourPrefs syncWithDisk]; - // Handle menubar theme changes fgMenuThemeColor = self.menuBarTextColor; // Cache colors to skip archiver userColor = [self colorByAdjustingForLightDark:[ourPrefs cpuUserColor]]; systemColor = [self colorByAdjustingForLightDark:[ourPrefs cpuSystemColor]]; - temperatureColor = [self colorByAdjustingForLightDark:[ourPrefs cpuTemperatureColor]]; + temperatureColor = [self colorByAdjustingForLightDark:[ourPrefs cpuTemperatureColor]]; - int numberOfCPUs = [ourPrefs cpuAvgLowerHalfProcs]?[cpuInfo numberOfCores]:[cpuInfo numberOfCPUs]; - - if ([ourPrefs cpuDisplayMode] & kCPUDisplayPercent) { + int numberOfCPUs = [ourPrefs cpuAvgLowerHalfProcs] ? [cpuInfo numberOfCores] : [cpuInfo numberOfCPUs]; + int cpuDisplayMode = [ourPrefs cpuDisplayMode]; + if (cpuDisplayMode & kCPUDisplayPercent) { // Calc the new width - NSAttributedString*string=[self percentStringForLoad:[ourPrefs cpuSumAllProcsPercent]?[cpuInfo numberOfCPUs]:1.0f - andColor:fgMenuThemeColor]; - percentWidth = (float)round([string size].width) + kCPUPercentDisplayBorderWidth; + NSAttributedString *string = [self percentStringForLoad:[ourPrefs cpuSumAllProcsPercent] ? [cpuInfo numberOfCPUs] : 1.0 + andColor:fgMenuThemeColor]; + percentWidth = (float)round([string size].width); // + kCPUPercentDisplayBorderWidth; } // Fix our menu size to match our new config menuWidth = 0; - if ([ourPrefs cpuDisplayMode] & kCPUDisplayHorizontalThermometer) { - menuWidth = [ourPrefs cpuMenuWidth]; - } - else { - if ([ourPrefs cpuDisplayMode] & kCPUDisplayPercent) { - menuWidth += (([ourPrefs cpuAvgAllProcs] ? 1 : numberOfCPUs) * percentWidth); - } - if ([ourPrefs cpuDisplayMode] & kCPUDisplayGraph) { - menuWidth += (([ourPrefs cpuAvgAllProcs] ? 1 : numberOfCPUs) * [ourPrefs cpuGraphLength]); - } - if ([ourPrefs cpuDisplayMode] & kCPUDisplayThermometer) { - menuWidth += (([ourPrefs cpuAvgAllProcs] ? 1 : numberOfCPUs) * kCPUThermometerDisplayWidth); - } - if (![ourPrefs cpuAvgAllProcs] && (numberOfCPUs > 1)) { - menuWidth += ((numberOfCPUs - 1) * kCPUDisplayMultiProcGapWidth); - } - } - if ([ourPrefs cpuShowTemperature]) { - cpuTemperatureDisplayWidth=1+[self renderTemperatureStringForString:@"66.6℃"].size.width; - menuWidth += cpuTemperatureDisplayWidth; - } - if(![ourPrefs cpuShowTemperature] && [ourPrefs cpuDisplayMode]==0){ - menuWidth=kCPULabelOnlyWidth; - } + if (cpuDisplayMode & kCPUDisplayHorizontalThermometer) { + menuWidth = [ourPrefs cpuMenuWidth]; + } + else { + BOOL cpuAvgAllProcs = [ourPrefs cpuAvgAllProcs]; + if (cpuDisplayMode & kCPUDisplayPercent) { + menuWidth += ((cpuAvgAllProcs ? 1 : numberOfCPUs) * percentWidth); + } + if (cpuDisplayMode & kCPUDisplayGraph) { + menuWidth += ((cpuAvgAllProcs ? 1 : numberOfCPUs) * [ourPrefs cpuGraphLength]); + } + if (cpuDisplayMode & kCPUDisplayThermometer) { + menuWidth += ((cpuAvgAllProcs ? 1 : numberOfCPUs) * kCPUThermometerDisplayWidth); + } + if (!cpuAvgAllProcs && (numberOfCPUs > 1)) { + menuWidth += ((numberOfCPUs - 1) * kCPUDisplayMultiProcGapWidth); + } + } + if ([ourPrefs cpuShowTemperature]) { + cpuTemperatureDisplayWidth = 1 + [self renderTemperatureStringForString:@"66.6℃"].size.width; + menuWidth += cpuTemperatureDisplayWidth; + } + if (![ourPrefs cpuShowTemperature] && cpuDisplayMode == 0) { + menuWidth = kCPULabelOnlyWidth; + } // Handle PowerMate if ([ourPrefs cpuPowerMate]) { // Load PowerMate if needed, this grabs control of the PowerMate @@ -795,55 +832,64 @@ - (void)configFromPrefs:(NSNotification *)notification { [powerMate setPulse:1.0]; break; } - } else { + } + else { NSLog(@"MenuMeterCPU unable to load PowerMate support."); } - } else { + } + else { // Release control if the user wants it for something else powerMate = nil; } - // Force initial update - statusItem.button.image=self.image; + statusItem.button.image = self.image; } // configFromPrefs - (void)getCPULoadForCPU:(uint32_t)processor - atPosition:(NSInteger)position - returnSystem:(double *)system - returnUser:(double *)user -{ - NSArray *currentLoad = [loadHistory lastObject]; - if(position!=-1){ - currentLoad=[loadHistory objectAtIndex:position]; - } + atPosition:(NSInteger)position + returnSystem:(double *)system + returnUser:(double *)user { + NSArray *currentLoad; + if (position < 0) { + currentLoad = [loadHistory lastObject]; + } + else { + currentLoad = [loadHistory objectAtIndex:position]; + } if (!currentLoad || ([currentLoad count] < processor)) { - *system = -1; - *user = -1; - return; - } - - if (![ourPrefs cpuAvgAllProcs]){ - MenuMeterCPULoad*load=currentLoad[processor]; - *system = load.system; - *user = load.user; - }else{ - double s=0,u=0; - int numberOfCPUs = [cpuInfo numberOfCPUs]; - for (uint32_t cpuNum = 0; cpuNum < numberOfCPUs; cpuNum++) { - MenuMeterCPULoad *load = currentLoad[cpuNum]; - s+=load.system; - u+=load.user; - } - s /= numberOfCPUs; - u /= numberOfCPUs; - *system=s; - *user=u; - } - // Sanity and limit - if (*system < 0) *system = 0; - if (*system > 1) *system = 1; - if (*user < 0) *user = 0; - if (*user > 1) *user = 1; + *system = -1; + *user = -1; + return; + } + + if (![ourPrefs cpuAvgAllProcs]) { + MenuMeterCPULoad *load = currentLoad[processor]; + *system = load.system; + *user = load.user; + } + else { + double s = 0, u = 0; + int numberOfCPUs = [cpuInfo numberOfCPUs]; + for (uint32_t cpuNum = 0; cpuNum < numberOfCPUs; cpuNum++) { + MenuMeterCPULoad *load = currentLoad[cpuNum]; + s += load.system; + u += load.user; + } + s /= numberOfCPUs; + u /= numberOfCPUs; + *system = s; + *user = u; + } + // Sanity and limit + if (*system < 0) + *system = 0; + if (*system > 1) + *system = 1; + if (*user < 0) + *user = 0; + if (*user > 1) + *user = 1; } + @end diff --git a/MenuExtras/MenuMeterCPU/MenuMeterCPUStats.h b/MenuExtras/MenuMeterCPU/MenuMeterCPUStats.h index a68843cd..2d0cc2cd 100644 --- a/MenuExtras/MenuMeterCPU/MenuMeterCPUStats.h +++ b/MenuExtras/MenuMeterCPU/MenuMeterCPUStats.h @@ -1,71 +1,82 @@ // // MenuMeterCPUStats.h // -// Reader object for CPU information and load +// Reader object for CPU information and load // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -#import +#import "LocalizedStrings.h" +#import "MenuMeterCPU.h" #import -#import -#import +#import #import #import #import -#import "MenuMeterCPU.h" -#import "LocalizedStrings.h" +#import +#import @interface MenuMeterCPULoad : NSObject -@property(nonatomic) double system; -@property(nonatomic) double user; +@property (nonatomic) double system; +@property (nonatomic) double user; @end @interface MenuMeterCPUStats : NSObject { // CPU name - NSString *cpuName; + NSString *cpuName; // CPU clock speed - NSString *clockSpeed; + NSString *clockSpeed; // Mach host - host_name_port_t machHost; + host_name_port_t machHost; // Default processor set - processor_set_name_port_t processorSet; + processor_set_name_port_t processorSet; // Previous processor tick data - processor_cpu_load_info_t priorCPUTicks; + processor_cpu_load_info_t priorCPUTicks; // Localized float display - NSNumberFormatter *twoDigitFloatFormatter; + NSNumberFormatter *twoDigitFloatFormatter; } // MenuMeterCPUStats // CPU info + - (NSString *)cpuName; + - (NSString *)cpuSpeed; + - (uint32_t)numberOfCPUs; + - (uint32_t)numberOfCores; + - (NSString *)processorDescription; + - (NSString *)coreDescription; // Load info + - (NSString *)currentProcessorTasks; + - (NSString *)loadAverage; + - (NSArray *)currentLoadBySorting:(BOOL)sorted; + - (float_t)cpuProximityTemperature; -- (NSString*)cpuPowerLimitStatus; + +- (NSString *)cpuPowerLimitStatus; @end diff --git a/MenuExtras/MenuMeterCPU/MenuMeterCPUStats.m b/MenuExtras/MenuMeterCPU/MenuMeterCPUStats.m index 2e7da2e8..e4b2215b 100644 --- a/MenuExtras/MenuMeterCPU/MenuMeterCPUStats.m +++ b/MenuExtras/MenuMeterCPU/MenuMeterCPUStats.m @@ -1,30 +1,30 @@ // // MenuMeterCPUStats.m // -// Reader object for CPU information and load +// Reader object for CPU information and load // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #import "MenuMeterCPUStats.h" -#import -#import "TemperatureReader.h" #import "MenuMeterDefaults.h" +#import "TemperatureReader.h" +#import #include @implementation MenuMeterCPULoad @@ -32,33 +32,34 @@ @implementation MenuMeterCPULoad /////////////////////////////////////////////////////////////// // -// Private methods +// Private methods // /////////////////////////////////////////////////////////////// @interface MenuMeterCPUStats (PrivateMethods) + - (NSString *)cpuPrettyName; + - (UInt32)clockFrequency; @end - /////////////////////////////////////////////////////////////// // -// Localized strings +// Localized strings // /////////////////////////////////////////////////////////////// -#define kProcessorNameFormat @"%u %@ @ %@" -#define kTaskThreadFormat @"%d tasks, %d threads" -#define kLoadAverageFormat @"%@, %@, %@" -#define kNoInfoErrorMessage @"No info available" -#define kHyperThreadsPerCoreFormat @" (%@ hyperthreads per core)" -#define kPhysicalCoresFormat @"%@%@ physical cores" -#define kCPUPowerLimitStatusFormat @"speed %@%%, scheduler %@%%" +#define kProcessorNameFormat @"%u %@ @ %@" +#define kTaskThreadFormat @"%d tasks, %d threads" +#define kLoadAverageFormat @"%@, %@, %@" +#define kNoInfoErrorMessage @"No info available" +#define kHyperThreadsPerCoreFormat @" (%@ hyperthreads per core)" +#define kPhysicalCoresFormat @"%@%@ physical cores" +#define kCPUPowerLimitStatusFormat @"speed %@%%, scheduler %@%%" /////////////////////////////////////////////////////////////// // -// init/dealloc +// init/dealloc // /////////////////////////////////////////////////////////////// @@ -67,7 +68,7 @@ @implementation MenuMeterCPUStats uint32_t coreCount; uint32_t packageCount; -- (id)init { +- (instancetype)init { // Allow super to init self = [super init]; @@ -95,37 +96,35 @@ - (id)init { } // Gather the clock rate string - uint32_t clockRate = [self clockFrequency]; - if (clockRate > 1000000000) { - clockSpeed = [NSString stringWithFormat:@"%@GHz", - [twoDigitFloatFormatter stringForObjectValue: - [NSNumber numberWithFloat:(float)clockRate / 1000000000]]]; - } else { - clockSpeed = [NSString stringWithFormat:@"%dMHz", clockRate / 1000000]; - } - if (!clockSpeed) { - return nil; - } + uint32_t clockRate = [self clockFrequency]; + if (clockRate > 1000000000) { + clockSpeed = [NSString stringWithFormat:@"%@GHz", [twoDigitFloatFormatter stringForObjectValue:[NSNumber numberWithDouble:clockRate / 1000000000]]]; + } + else { + clockSpeed = [NSString stringWithFormat:@"%dMHz", clockRate / 1000000]; + } + if (!clockSpeed) { + return nil; + } // Gather the cpu count - size_t sysctlLength = sizeof(cpuCount); - int mib[2] = { CTL_HW, HW_NCPU }; + size_t sysctlLength = sizeof(cpuCount); + int mib[2] = {CTL_HW, HW_NCPU}; if (sysctl(mib, 2, &cpuCount, &sysctlLength, NULL, 0)) { return nil; } - size_t size=sizeof(coreCount); - if(sysctlbyname("hw.physicalcpu", &coreCount, &size, NULL, 0)){ - coreCount=cpuCount; - } + size_t size = sizeof(coreCount); + if (sysctlbyname("hw.physicalcpu", &coreCount, &size, NULL, 0)) { + coreCount = cpuCount; + } - size=sizeof(packageCount); - if(sysctlbyname("hw.packages", &packageCount, &size, NULL, 0)){ - packageCount=1; - } + size = sizeof(packageCount); + if (sysctlbyname("hw.packages", &packageCount, &size, NULL, 0)) { + packageCount = 1; + } - // Set up our mach host and default processor set for later calls machHost = mach_host_self(); processor_set_default(machHost, &processorSet); @@ -139,7 +138,7 @@ - (id)init { if (err != KERN_SUCCESS) { return nil; } - priorCPUTicks = (processor_cpu_load_info_t) malloc(processorCount * sizeof(struct processor_cpu_load_info)); + priorCPUTicks = (processor_cpu_load_info_t)malloc(processorCount * sizeof(struct processor_cpu_load_info)); for (natural_t i = 0; i < processorCount; i++) { for (natural_t j = 0; j < CPU_STATE_MAX; j++) { priorCPUTicks[i].cpu_ticks[j] = processorTickInfo[i].cpu_ticks[j]; @@ -154,26 +153,23 @@ - (id)init { - (void)dealloc { - if (priorCPUTicks) free(priorCPUTicks); + if (priorCPUTicks) + free(priorCPUTicks); } // dealloc /////////////////////////////////////////////////////////////// // -// CPU info +// CPU info // /////////////////////////////////////////////////////////////// - (NSString *)cpuName { - return cpuName; - } // cpuName - (NSString *)cpuSpeed { - return clockSpeed; - } // cpuSpeed - (uint32_t)numberOfCPUs { @@ -181,30 +177,31 @@ - (uint32_t)numberOfCPUs { } // numberOfCPUs - (uint32_t)numberOfCores { - return coreCount; -} - --(NSString*)packages{ - if(packageCount==1){ - return @""; - }else{ - return [NSString stringWithFormat:@"%@x ",@(packageCount)]; - } + return coreCount; } + +- (NSString *)packages { + if (packageCount == 1) { + return @""; + } + return [NSString stringWithFormat:@"%@x ", @(packageCount)]; +} + - (NSString *)processorDescription { return [NSString stringWithFormat:@"%@%@ @ %@", [self packages], [self cpuName], [self cpuSpeed]]; } // processorDescription + - (NSString *)coreDescription { - NSString*hyperinfo=@""; - if(cpuCount!=coreCount){ - hyperinfo=[NSString stringWithFormat:[localizedStrings objectForKey:kHyperThreadsPerCoreFormat],@(cpuCount/coreCount)]; - } - return [NSString stringWithFormat:@"%@%@", [NSString stringWithFormat:[localizedStrings objectForKey:kPhysicalCoresFormat],[self packages],@(coreCount/packageCount)],hyperinfo]; + NSString *hyperinfo = @""; + if (cpuCount != coreCount) { + hyperinfo = [NSString stringWithFormat:[localizedStrings objectForKey:kHyperThreadsPerCoreFormat], @(cpuCount / coreCount)]; + } + return [NSString stringWithFormat:@"%@%@", [NSString stringWithFormat:[localizedStrings objectForKey:kPhysicalCoresFormat], [self packages], @(coreCount / packageCount)], hyperinfo]; } // coreDescription /////////////////////////////////////////////////////////////// // -// Load info +// Load info // /////////////////////////////////////////////////////////////// @@ -214,12 +211,13 @@ - (NSString *)currentProcessorTasks { mach_msg_type_number_t count = PROCESSOR_SET_LOAD_INFO_COUNT; kern_return_t err = processor_set_statistics(processorSet, PROCESSOR_SET_LOAD_INFO, (processor_set_info_t)&loadInfo, &count); - + if (err != KERN_SUCCESS) { return [localizedStrings objectForKey:kNoInfoErrorMessage]; - } else { + } + else { return [NSString stringWithFormat:[localizedStrings objectForKey:kTaskThreadFormat], - loadInfo.task_count, loadInfo.thread_count]; + loadInfo.task_count, loadInfo.thread_count]; } } // currentProcessorTasks @@ -227,19 +225,20 @@ - (NSString *)currentProcessorTasks { - (NSString *)loadAverage { // Fetch using getloadavg() to better match top, from Michael Nordmeyer (http://goodyworks.com) - double loads[3] = { 0, 0, 0 }; + double loads[3] = {0, 0, 0}; if (getloadavg(loads, 3) != 3) { return [localizedStrings objectForKey:kNoInfoErrorMessage]; - } else { + } + else { return [NSString stringWithFormat:[localizedStrings objectForKey:kLoadAverageFormat], - [twoDigitFloatFormatter stringForObjectValue:[NSNumber numberWithFloat:(float)loads[0]]], - [twoDigitFloatFormatter stringForObjectValue:[NSNumber numberWithFloat:(float)loads[1]]], - [twoDigitFloatFormatter stringForObjectValue:[NSNumber numberWithFloat:(float)loads[2]]]]; + [twoDigitFloatFormatter stringForObjectValue:[NSNumber numberWithDouble:loads[0]]], + [twoDigitFloatFormatter stringForObjectValue:[NSNumber numberWithDouble:loads[1]]], + [twoDigitFloatFormatter stringForObjectValue:[NSNumber numberWithDouble:loads[2]]]]; } } // loadAverage -- (NSArray *)currentLoadBySorting: (BOOL)sorted { +- (NSArray *)currentLoadBySorting:(BOOL)sorted { // Read the current ticks natural_t processorCount; @@ -247,7 +246,8 @@ - (NSArray *)currentLoadBySorting: (BOOL)sorted { mach_msg_type_number_t processorInfoCount; kern_return_t err = host_processor_info(machHost, PROCESSOR_CPU_LOAD_INFO, &processorCount, (processor_info_array_t *)&processorTickInfo, &processorInfoCount); - if (err != KERN_SUCCESS) return nil; + if (err != KERN_SUCCESS) + return nil; // We have valid info so build return array NSMutableArray *loadInfo = [NSMutableArray array]; @@ -259,12 +259,14 @@ - (NSArray *)currentLoadBySorting: (BOOL)sorted { if (processorTickInfo[i].cpu_ticks[CPU_STATE_SYSTEM] >= priorCPUTicks[i].cpu_ticks[CPU_STATE_SYSTEM]) { system = processorTickInfo[i].cpu_ticks[CPU_STATE_SYSTEM] - priorCPUTicks[i].cpu_ticks[CPU_STATE_SYSTEM]; - } else { + } + else { system = processorTickInfo[i].cpu_ticks[CPU_STATE_SYSTEM] + (UINT_MAX - priorCPUTicks[i].cpu_ticks[CPU_STATE_SYSTEM] + 1); } if (processorTickInfo[i].cpu_ticks[CPU_STATE_USER] >= priorCPUTicks[i].cpu_ticks[CPU_STATE_USER]) { user = processorTickInfo[i].cpu_ticks[CPU_STATE_USER] - priorCPUTicks[i].cpu_ticks[CPU_STATE_USER]; - } else { + } + else { user = processorTickInfo[i].cpu_ticks[CPU_STATE_USER] + (ULONG_MAX - priorCPUTicks[i].cpu_ticks[CPU_STATE_USER] + 1); } // Count nice as user (nice slot non-zero only on OS versions prior to 10.4) @@ -272,18 +274,20 @@ - (NSArray *)currentLoadBySorting: (BOOL)sorted { // pretending its going to get fixed. if (processorTickInfo[i].cpu_ticks[CPU_STATE_NICE] >= priorCPUTicks[i].cpu_ticks[CPU_STATE_NICE]) { user += processorTickInfo[i].cpu_ticks[CPU_STATE_NICE] - priorCPUTicks[i].cpu_ticks[CPU_STATE_NICE]; - } else { + } + else { user += processorTickInfo[i].cpu_ticks[CPU_STATE_NICE] + (ULONG_MAX - priorCPUTicks[i].cpu_ticks[CPU_STATE_NICE] + 1); } if (processorTickInfo[i].cpu_ticks[CPU_STATE_IDLE] >= priorCPUTicks[i].cpu_ticks[CPU_STATE_IDLE]) { idle = processorTickInfo[i].cpu_ticks[CPU_STATE_IDLE] - priorCPUTicks[i].cpu_ticks[CPU_STATE_IDLE]; - } else { + } + else { idle = processorTickInfo[i].cpu_ticks[CPU_STATE_IDLE] + (ULONG_MAX - priorCPUTicks[i].cpu_ticks[CPU_STATE_IDLE] + 1); } total = system + user + idle; float normalize = (total < 1) ? 1 : (1.0 / total); - + MenuMeterCPULoad *load = [[MenuMeterCPULoad alloc] init]; load.system = system * normalize; load.user = user * normalize; @@ -297,26 +301,26 @@ - (NSArray *)currentLoadBySorting: (BOOL)sorted { } } - // Sort the load if necessary - if (sorted == YES) { - NSMutableArray *sorted = [NSMutableArray array]; - processorCount=(natural_t)[loadInfo count]; - for (natural_t i = 0; i < processorCount; i++) { - float maxSum = 0.0f; - natural_t maxIndex = 0; - for (natural_t j = 0; j < (processorCount - i); j++) { - MenuMeterCPULoad *load = [loadInfo objectAtIndex: j]; - float sum = load.system + load.user; - if (sum > maxSum) { - maxSum = sum; - maxIndex = j; - } - } - [sorted addObject: [loadInfo objectAtIndex: maxIndex]]; - [loadInfo removeObjectAtIndex: maxIndex]; - } - loadInfo = sorted; - } + // Sort the load if necessary + if (sorted == YES) { + NSMutableArray *sorted = [NSMutableArray array]; + processorCount = (natural_t)[loadInfo count]; + for (natural_t i = 0; i < processorCount; i++) { + float maxSum = 0.0; + natural_t maxIndex = 0; + for (natural_t j = 0; j < (processorCount - i); j++) { + MenuMeterCPULoad *load = [loadInfo objectAtIndex:j]; + float sum = load.system + load.user; + if (sum > maxSum) { + maxSum = sum; + maxIndex = j; + } + } + [sorted addObject:[loadInfo objectAtIndex:maxIndex]]; + [loadInfo removeObjectAtIndex:maxIndex]; + } + loadInfo = sorted; + } // Dealloc vm_deallocate(mach_task_self(), (vm_address_t)processorTickInfo, (vm_size_t)(processorInfoCount * sizeof(natural_t))); @@ -327,50 +331,50 @@ - (NSArray *)currentLoadBySorting: (BOOL)sorted { } // currentLoad - (float_t)cpuProximityTemperature { - NSString*sensor=[[MenuMeterDefaults sharedMenuMeterDefaults] cpuTemperatureSensor]; - if([sensor isEqualToString:kCPUTemperatureSensorDefault]){ - sensor=[TemperatureReader defaultSensor]; - } - return [TemperatureReader temperatureOfSensorWithName:sensor]; + NSString *sensor = [[MenuMeterDefaults sharedMenuMeterDefaults] cpuTemperatureSensor]; + if ([sensor isEqualToString:kCPUTemperatureSensorDefault]) { + sensor = [TemperatureReader defaultSensor]; + } + return [TemperatureReader temperatureOfSensorWithName:sensor]; } // cpuProximityTemperature /////////////////////////////////////////////////////////////// // -// Utility +// Utility // /////////////////////////////////////////////////////////////// - (NSString *)cpuPrettyName { -#if 1 - - char cpumodel[64]; - size_t size = sizeof(cpumodel); - if (!sysctlbyname("machdep.cpu.brand_string", cpumodel, &size, NULL, 0)){ - NSString*s=[NSString stringWithUTF8String:cpumodel]; - NSRange r; - r=[s rangeOfString:@"@"]; - if(r.location!=NSNotFound){ - s=[s substringToIndex:r.location]; - } - r=[s rangeOfString:@"CPU"]; - if(r.location!=NSNotFound){ - s=[s substringToIndex:r.location]; - } - s=[s stringByReplacingOccurrencesOfString:@"(TM)" withString:@"™"]; - s=[s stringByReplacingOccurrencesOfString:@"(R)" withString:@"®"]; - - NXArchInfo const *archInfo = NXGetLocalArchInfo(); - if (archInfo) { - s = [s stringByAppendingFormat:@" (%@)",[NSString stringWithCString:archInfo->description]]; - } - - return s; - } - return @"???"; +#if 1 + + char cpumodel[64]; + size_t size = sizeof(cpumodel); + if (!sysctlbyname("machdep.cpu.brand_string", cpumodel, &size, NULL, 0)) { + NSString *s = [NSString stringWithUTF8String:cpumodel]; + NSRange r; + r = [s rangeOfString:@"@"]; + if (r.location != NSNotFound) { + s = [s substringToIndex:r.location]; + } + r = [s rangeOfString:@"CPU"]; + if (r.location != NSNotFound) { + s = [s substringToIndex:r.location]; + } + s = [s stringByReplacingOccurrencesOfString:@"(TM)" withString:@"™"]; + s = [s stringByReplacingOccurrencesOfString:@"(R)" withString:@"®"]; + + NXArchInfo const *archInfo = NXGetLocalArchInfo(); + if (archInfo) { + s = [s stringByAppendingFormat:@" (%s)", archInfo->description]; + } + + return s; + } + return @"???"; #else // Start with nothing - NSString *prettyName = @"Unknown CPU"; + NSString *prettyName = @"Unknown CPU"; // Try older API for the pretty name (Aquamon demonstrated this) NXArchInfo const *archInfo = NXGetLocalArchInfo(); @@ -387,11 +391,13 @@ - (NSString *)cpuPrettyName { if (err == noErr) { if (gestaltVal == gestaltCPUApollo) { prettyName = @"PowerPC 7455"; - } else if (gestaltVal == gestaltCPUG47447) { + } + else if (gestaltVal == gestaltCPUG47447) { // Gestalt says 7447, but CHUD says 7457. Let's believe CHUD. // Patch from Alex Eddy prettyName = @"PowerPC 7457"; - } else if (gestaltVal == gestaltCPU750FX) { + } + else if (gestaltVal == gestaltCPU750FX) { prettyName = @"PowerPC 750fx"; } } @@ -400,40 +406,46 @@ - (NSString *)cpuPrettyName { } // _cpuPrettyName -- (UInt32) clockFrequency { - uint32_t clockRate = 0; - - // First try with sysctl - int mib[2] = { CTL_HW, HW_CPU_FREQ }; - size_t sysctlLength = sizeof(clockRate); - int res = sysctl(mib, 2, &clockRate, &sysctlLength, NULL, 0); - - // Try using IOKit - if (res != 0) { - mach_port_t platformExpertDevice = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice")); - CFTypeRef platformClockFrequency = IORegistryEntryCreateCFProperty(platformExpertDevice, CFSTR("clock-frequency"), kCFAllocatorDefault, 0); - if (CFGetTypeID(platformClockFrequency) == CFDataGetTypeID()) { - const CFDataRef platformClockFrequencyData = (const CFDataRef) platformClockFrequency; - const UInt8* clockFreqBytes = CFDataGetBytePtr(platformClockFrequencyData); - clockRate = CFSwapInt32BigToHost(*(UInt32*)(clockFreqBytes)) * 1000; - CFRelease(platformClockFrequency); - } - IOObjectRelease(platformExpertDevice); - } - - return clockRate; +- (UInt32)clockFrequency { + uint32_t clockRate = 0; + + // First try with sysctl + int mib[2] = {CTL_HW, HW_CPU_FREQ}; + size_t sysctlLength = sizeof(clockRate); + int res = sysctl(mib, 2, &clockRate, &sysctlLength, NULL, 0); + + // Try using IOKit + if (res != 0) { + mach_port_t platformExpertDevice = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice")); + CFTypeRef platformClockFrequency = IORegistryEntryCreateCFProperty(platformExpertDevice, CFSTR("clock-frequency"), kCFAllocatorDefault, 0); + if (CFGetTypeID(platformClockFrequency) == CFDataGetTypeID()) { + const CFDataRef platformClockFrequencyData = (const CFDataRef)platformClockFrequency; + const UInt8 *clockFreqBytes = CFDataGetBytePtr(platformClockFrequencyData); + clockRate = CFSwapInt32BigToHost(*(UInt32 *)(clockFreqBytes)) * 1000; + } + if (platformClockFrequency) { + CFRelease(platformClockFrequency); + } + if (platformExpertDevice) { + IOObjectRelease(platformExpertDevice); + } + } + + return clockRate; } // getClockFrequency -- (NSString*)cpuPowerLimitStatus -{ - CFDictionaryRef dic=NULL; - IOPMCopyCPUPowerStatus(&dic); - if(dic){ - NSDictionary*d=CFBridgingRelease(dic); - NSNumber*speedLimit=d[[NSString stringWithUTF8String:kIOPMCPUPowerLimitProcessorSpeedKey]]; - NSNumber*schedulerLimit=d[[NSString stringWithUTF8String:kIOPMCPUPowerLimitSchedulerTimeKey]]; - return [NSString stringWithFormat:[localizedStrings objectForKey:kCPUPowerLimitStatusFormat],speedLimit,schedulerLimit]; - }else{ - return nil; - } + +- (NSString *)cpuPowerLimitStatus { + CFDictionaryRef dic = NULL; + IOPMCopyCPUPowerStatus(&dic); + if (dic) { + NSDictionary *d = CFBridgingRelease(dic); + NSNumber *speedLimit = d[[NSString stringWithUTF8String:kIOPMCPUPowerLimitProcessorSpeedKey]]; + NSNumber *schedulerLimit = d[[NSString stringWithUTF8String:kIOPMCPUPowerLimitSchedulerTimeKey]]; + return [NSString stringWithFormat:[localizedStrings objectForKey:kCPUPowerLimitStatusFormat], speedLimit, schedulerLimit]; + } + else { + return nil; + } } + @end diff --git a/MenuExtras/MenuMeterCPU/MenuMeterCPUTopProcesses.h b/MenuExtras/MenuMeterCPU/MenuMeterCPUTopProcesses.h index d0fe7769..4376cac2 100644 --- a/MenuExtras/MenuMeterCPU/MenuMeterCPUTopProcesses.h +++ b/MenuExtras/MenuMeterCPU/MenuMeterCPUTopProcesses.h @@ -3,39 +3,41 @@ // // Reader object for top CPU hogging process list // -// Copyright (c) 2018 Hofi +// Copyright (c) 2018 Hofi // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #import -extern NSString* const kProcessListItemPIDKey; -extern NSString* const kProcessListItemProcessNameKey; -extern NSString* const kProcessListItemProcessPathKey; -extern NSString* const kProcessListItemUserIDKey; -extern NSString* const kProcessListItemUserNameKey; -extern NSString* const kProcessListItemCPUKey; +extern NSString *const kProcessListItemPIDKey; +extern NSString *const kProcessListItemProcessNameKey; +extern NSString *const kProcessListItemProcessPathKey; +extern NSString *const kProcessListItemUserIDKey; +extern NSString *const kProcessListItemUserNameKey; +extern NSString *const kProcessListItemCPUKey; @interface MenuMeterCPUTopProcesses : NSObject // Basic process info for the top maxItem most CPU hugging processes + - (NSArray *)runningProcessesByCPUUsage:(NSUInteger)maxItem; - (void)startUpdateProcessList; + - (void)stopUpdateProcessList; @end diff --git a/MenuExtras/MenuMeterCPU/MenuMeterCPUTopProcesses.m b/MenuExtras/MenuMeterCPU/MenuMeterCPUTopProcesses.m index d9f7521f..71b8defb 100644 --- a/MenuExtras/MenuMeterCPU/MenuMeterCPUTopProcesses.m +++ b/MenuExtras/MenuMeterCPU/MenuMeterCPUTopProcesses.m @@ -1,173 +1,162 @@ // // MenuMeterCPUTopProcesses.mm // -// Reader object for top CPU hogging process list +// Reader object for top CPU hogging process list // // Copyright (c) 2018 Hofi // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #import "MenuMeterCPUTopProcesses.h" #import "MenuMeterCPU.h" - /////////////////////////////////////////////////////////////// // -// Process info item key strings +// Process info item key strings // /////////////////////////////////////////////////////////////// -NSString* const kProcessListItemPIDKey = @"processID"; -NSString* const kProcessListItemProcessNameKey = @"processName"; -NSString* const kProcessListItemProcessPathKey = @"processPath"; -NSString* const kProcessListItemUserIDKey = @"userID"; -NSString* const kProcessListItemUserNameKey = @"userName"; -NSString* const kProcessListItemCPUKey = @"cpuPercent"; +NSString *const kProcessListItemPIDKey = @"processID"; +NSString *const kProcessListItemProcessNameKey = @"processName"; +NSString *const kProcessListItemProcessPathKey = @"processPath"; +NSString *const kProcessListItemUserIDKey = @"userID"; +NSString *const kProcessListItemUserNameKey = @"userName"; +NSString *const kProcessListItemCPUKey = @"cpuPercent"; /////////////////////////////////////////////////////////////// // -// Private categories +// Private categories // /////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////// // -// init/dealloc +// init/dealloc // /////////////////////////////////////////////////////////////// -@implementation MenuMeterCPUTopProcesses -{ - NSArray*processes; - NSTask*task; - NSPipe*pipe; - NSString*buffer; - int parseState; //0 is before the first PID, COMMAND ... ; 1 is just after it saw PID, ... - NSMutableArray*tempArray; +@implementation MenuMeterCPUTopProcesses { + NSArray *processes; + NSTask *task; + NSPipe *pipe; + NSString *buffer; + int parseState; // 0 is before the first PID, COMMAND ... ; 1 is just after it saw PID, ... + NSMutableArray *tempArray; } - --(instancetype)init -{ - self=[super init]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(taskOutput:) - name:NSFileHandleReadCompletionNotification - object:nil]; - return self; + +- (instancetype)init { + self = [super init]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(taskOutput:) + name:NSFileHandleReadCompletionNotification + object:nil]; + return self; } --(void)taskOutput:(NSNotification*)n -{ - NSFileHandle*fh=[n object]; - if(![[pipe fileHandleForReading] isEqualTo: fh]){ - return; - } - NSData*d=[n userInfo][@"NSFileHandleNotificationDataItem"]; - if([d length]){ - NSString*s=[[NSString alloc] initWithData:d encoding:NSUTF8StringEncoding]; - buffer=[buffer stringByAppendingString:s]; - while([buffer containsString:@"\n"]){ - NSUInteger i=[buffer rangeOfString:@"\n"].location; - NSString*x=[buffer substringToIndex:i]; - [self dealWithLine:x]; - buffer=[buffer substringFromIndex:i+1]; - } - [fh readInBackgroundAndNotifyForModes:@[NSRunLoopCommonModes]]; - } + +- (void)taskOutput:(NSNotification *)n { + NSFileHandle *fh = [n object]; + if (![[pipe fileHandleForReading] isEqualTo:fh]) { + return; + } + NSData *d = [n userInfo][@"NSFileHandleNotificationDataItem"]; + if ([d length]) { + NSString *s = [[NSString alloc] initWithData:d encoding:NSUTF8StringEncoding]; + buffer = [buffer stringByAppendingString:s]; + while ([buffer containsString:@"\n"]) { + NSUInteger i = [buffer rangeOfString:@"\n"].location; + NSString *x = [buffer substringToIndex:i]; + [self dealWithLine:x]; + buffer = [buffer substringFromIndex:i + 1]; + } + [fh readInBackgroundAndNotifyForModes:@[NSRunLoopCommonModes]]; + } } - + - (void)startUpdateProcessList { - parseState=0; - buffer=[NSString string]; - task = [NSTask new]; - task.launchPath = @"/usr/bin/top"; - task.arguments =[[NSString stringWithFormat:@"-s 1 -l 0 -stats pid,cpu,uid,user,command -o cpu -n %@", @(kCPUrocessCountMax)] componentsSeparatedByString:@" "]; - - pipe = [NSPipe pipe]; - task.standardOutput = pipe; - [[pipe fileHandleForReading] readInBackgroundAndNotifyForModes:@[NSRunLoopCommonModes]]; - [task launch]; + parseState = 0; + buffer = [NSString string]; + task = [NSTask new]; + task.launchPath = @"/usr/bin/top"; + task.arguments = [[NSString stringWithFormat:@"-s 1 -l 0 -stats pid,cpu,uid,user,command -o cpu -n %@", @(kCPUrocessCountMax)] componentsSeparatedByString:@" "]; + + pipe = [NSPipe pipe]; + task.standardOutput = pipe; + [[pipe fileHandleForReading] readInBackgroundAndNotifyForModes:@[NSRunLoopCommonModes]]; + [task launch]; } // startUpdateProcessList - + - (void)stopUpdateProcessList { - [task terminate]; - task=nil; - buffer=nil; + [task terminate]; + task = nil; + buffer = nil; } // stopUpdateProcessList - -- (NSArray *)runningProcessesByCPUUsage:(NSUInteger)maxItem -{ - return [processes subarrayWithRange:NSMakeRange(0,MIN(maxItem,processes.count))]; + +- (NSArray *)runningProcessesByCPUUsage:(NSUInteger)maxItem { + return [processes subarrayWithRange:NSMakeRange(0, MIN(maxItem, processes.count))]; } --(void)dealWithLine:(NSString*)s -{ - if(parseState==0){ - if([s hasPrefix:@"PID"]){ - parseState=1; - tempArray=[NSMutableArray array]; - } - return; - } - if([s hasPrefix:@"Processes:"]){ - parseState=0; - // one sample completed - processes=tempArray; - return; - } - - NSArray*a=[s componentsSeparatedByString:@" "]; - NSMutableArray*x=[NSMutableArray array]; - for(NSString*i in a){ - if(![i isEqualToString:@""]){ - [x addObject:i]; - } - } - NSArray*commandName=[x subarrayWithRange:NSMakeRange(4,x.count-4)]; - NSDictionary* entry = @{ kProcessListItemPIDKey:x[0], - kProcessListItemCPUKey:x[1], - kProcessListItemUserIDKey:x[2], - kProcessListItemUserNameKey:x[3], - kProcessListItemProcessNameKey:[self normalizedCommand:[commandName componentsJoinedByString:@" "]] - }; - [tempArray addObject:entry]; + +- (void)dealWithLine:(NSString *)s { + if (parseState == 0) { + if ([s hasPrefix:@"PID"]) { + parseState = 1; + tempArray = [NSMutableArray array]; + } + return; + } + if ([s hasPrefix:@"Processes:"]) { + parseState = 0; + // one sample completed + processes = tempArray; + return; + } + + NSArray *a = [s componentsSeparatedByString:@" "]; + NSMutableArray *x = [NSMutableArray array]; + for (NSString *i in a) { + if (![i isEqualToString:@""]) { + [x addObject:i]; + } + } + NSArray *commandName = [x subarrayWithRange:NSMakeRange(4, x.count - 4)]; + NSDictionary *entry = @{kProcessListItemPIDKey: x[0], + kProcessListItemCPUKey: x[1], + kProcessListItemUserIDKey: x[2], + kProcessListItemUserNameKey: x[3], + kProcessListItemProcessNameKey: [self normalizedCommand:[commandName componentsJoinedByString:@" "]]}; + [tempArray addObject:entry]; } +- (NSString *)normalizedCommand:(NSString *)name { + NSString *result = name; + + // remove leading/trailing whitespaces + result = [result stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + + // remove login shell prefixes + for (int i = 0; i < 2; ++i) { + if (name.length > 0) { + result = [result stringByReplacingOccurrencesOfString:@"-" withString:@"" options:0 range:NSMakeRange(0, 1)]; + } + } + // continue other clean up here + return result; -- (NSString *)normalizedCommand:(NSString *)name -{ - NSString* result = name; - - // remove leading/trailing whitespaces - result = [result stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; - - // remove login shell prefixes - for (int i = 0; i < 2; ++i) { - if (name.length > 0) { - result = [result stringByReplacingOccurrencesOfString:@"-" withString:@"" options:0 range:NSMakeRange(0, 1)]; - } - } - - // continue other clean up here - - return result; - } // normalizedCommand: - @end diff --git a/MenuExtras/MenuMeterCPU/MenuMeterUptime.h b/MenuExtras/MenuMeterCPU/MenuMeterUptime.h index f2a85434..caafa92e 100644 --- a/MenuExtras/MenuMeterCPU/MenuMeterUptime.h +++ b/MenuExtras/MenuMeterCPU/MenuMeterUptime.h @@ -1,34 +1,35 @@ // // MenuMeterUptime.h // -// Reader object for uptime +// Reader object for uptime // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -#import #import "LocalizedStrings.h" +#import @interface MenuMeterUptime : NSObject { } // MenuMeterUptime // Uptime info + - (NSString *)uptime; @end diff --git a/MenuExtras/MenuMeterCPU/MenuMeterUptime.m b/MenuExtras/MenuMeterCPU/MenuMeterUptime.m index 04afb45a..16359fae 100644 --- a/MenuExtras/MenuMeterCPU/MenuMeterUptime.m +++ b/MenuExtras/MenuMeterCPU/MenuMeterUptime.m @@ -1,52 +1,50 @@ // // MenuMeterUptime.m // -// Reader object for uptime +// Reader object for uptime // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #import "MenuMeterUptime.h" -#import #import - +#import /////////////////////////////////////////////////////////////// // -// Localized strings +// Localized strings // /////////////////////////////////////////////////////////////// -#define kUptimeUnavailable @"Unavailable" -#define kUptimeZeroDayFormat @"%02ld:%02ld:%02ld" -#define kUptimeOneDayFormat @"%ld day %02ld:%02ld:%02ld" -#define kUptimeMultiDayFormat @"%ld days %02ld:%02ld:%02ld" - +#define kUptimeUnavailable @"Unavailable" +#define kUptimeZeroDayFormat @"%02ld:%02ld:%02ld" +#define kUptimeOneDayFormat @"%ld day %02ld:%02ld:%02ld" +#define kUptimeMultiDayFormat @"%ld days %02ld:%02ld:%02ld" /////////////////////////////////////////////////////////////// // -// init/dealloc +// init/dealloc // /////////////////////////////////////////////////////////////// @implementation MenuMeterUptime -- (id)init { +- (instancetype)init { // Allow super to init self = [super init]; @@ -65,11 +63,11 @@ - (id)init { } // init - // dealloc +// dealloc /////////////////////////////////////////////////////////////// // -// Uptime info +// Uptime info // /////////////////////////////////////////////////////////////// @@ -80,7 +78,7 @@ - (NSString *)uptime { // Boot time struct timeval bootTime; - int mib[2] = { CTL_KERN, KERN_BOOTTIME }; + int mib[2] = {CTL_KERN, KERN_BOOTTIME}; size_t bootTimeSize = sizeof(bootTime); if (sysctl(mib, 2, &bootTime, &bootTimeSize, NULL, 0)) { return [localizedStrings objectForKey:kUptimeZeroDayFormat]; @@ -100,13 +98,15 @@ - (NSString *)uptime { NSString *uptimeDesc = nil; if (days > 1) { uptimeDesc = [NSString stringWithFormat:[localizedStrings objectForKey:kUptimeMultiDayFormat], - days, hours, minutes, seconds]; - } else if (days == 1) { + days, hours, minutes, seconds]; + } + else if (days == 1) { uptimeDesc = [NSString stringWithFormat:[localizedStrings objectForKey:kUptimeOneDayFormat], - days, hours, minutes, seconds]; - } else { + days, hours, minutes, seconds]; + } + else { uptimeDesc = [NSString stringWithFormat:[localizedStrings objectForKey:kUptimeZeroDayFormat], - hours, minutes, seconds]; + hours, minutes, seconds]; } // Send the string back diff --git a/MenuExtras/MenuMeterDisk/MenuMeterDiskExtra.h b/MenuExtras/MenuMeterDisk/MenuMeterDiskExtra.h index 7371c1b2..a6916a74 100644 --- a/MenuExtras/MenuMeterDisk/MenuMeterDiskExtra.h +++ b/MenuExtras/MenuMeterDisk/MenuMeterDiskExtra.h @@ -1,50 +1,49 @@ // // MenuMeterDiskExtra.h // -// Menu Extra implementation +// Menu Extra implementation // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -#import -#import -#import "MenuMeters.h" #import "MenuMeterDefaults.h" #import "MenuMeterDisk.h" #import "MenuMeterDiskIO.h" #import "MenuMeterDiskSpace.h" #import "MenuMeterWorkarounds.h" - +#import "MenuMeters.h" +#import +#import @interface MenuMeterDiskExtra : NSMenuExtra { // Menu Extra necessities - NSMenu *extraMenu; + NSMenu *extraMenu; // Pref object - MenuMeterDefaults *ourPrefs; + MenuMeterDefaults *ourPrefs; // Info gatherers - MenuMeterDiskIO *diskIOMonitor; - MenuMeterDiskSpace *diskSpaceMonitor; + MenuMeterDiskIO *diskIOMonitor; + MenuMeterDiskSpace *diskSpaceMonitor; // Display state and images - NSImage *idleImage, *readImage, *writeImage, *readwriteImage; - DiskIOActivityType displayedActivity; + NSImage *idleImage, *readImage, *writeImage, *readwriteImage; + DiskIOActivityType displayedActivity; // Theme support - NSColor *fgMenuThemeColor; + NSColor *fgMenuThemeColor; } // MenuMeterDiskExtra diff --git a/MenuExtras/MenuMeterDisk/MenuMeterDiskExtra.m b/MenuExtras/MenuMeterDisk/MenuMeterDiskExtra.m index 377f8b5a..0a958225 100644 --- a/MenuExtras/MenuMeterDisk/MenuMeterDiskExtra.m +++ b/MenuExtras/MenuMeterDisk/MenuMeterDiskExtra.m @@ -1,62 +1,63 @@ // // MenuMeterDiskExtra.m // -// Menu Extra implementation +// Menu Extra implementation // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #import "MenuMeterDiskExtra.h" - /////////////////////////////////////////////////////////////// // -// Private methods +// Private methods // /////////////////////////////////////////////////////////////// @interface MenuMeterDiskExtra (PrivateMethods) // Menu content + - (NSArray *)diskSpaceMenuItemImages:(NSArray *)driveDetails; // Menu actions + - (void)openOrEjectVolume:(id)sender; // Prefs + - (void)configFromPrefs:(NSNotification *)notification; @end - /////////////////////////////////////////////////////////////// // -// init/unload/dealloc +// init/unload/dealloc // /////////////////////////////////////////////////////////////// @implementation MenuMeterDiskExtra -- init { +- (instancetype)init { - self = [super initWithBundleID:kDiskMenuBundleID]; + self = [super initWithBundleID:kDiskMenuBundleID]; if (!self) { return nil; } - ourPrefs = [MenuMeterDefaults sharedMenuMeterDefaults]; + ourPrefs = [MenuMeterDefaults sharedMenuMeterDefaults]; if (!ourPrefs) { NSLog(@"MenuMeterDisk unable to connect to preferences. Abort."); return nil; @@ -85,7 +86,6 @@ @implementation MenuMeterDiskExtra // Disable menu autoenabling [extraMenu setAutoenablesItems:NO]; - // And configure directly from prefs on first load [self configFromPrefs:nil]; @@ -98,22 +98,22 @@ @implementation MenuMeterDiskExtra // Config initial state displayedActivity = kDiskActivityIdle; - // And hand ourself back to SystemUIServer - NSLog(@"MenuMeterDisk loaded."); - return self; + // And hand ourself back to SystemUIServer + MMLog(@"MenuMeterDisk loaded."); + return self; } // initWithBundle - // dealloc +// dealloc /////////////////////////////////////////////////////////////// // -// NSMenuExtra view callbacks +// NSMenuExtra view callbacks // /////////////////////////////////////////////////////////////// - (NSImage *)image { - [self setupAppearance]; + [self setupAppearance]; // Switch on state switch (displayedActivity) { @@ -144,11 +144,13 @@ - (NSMenu *)menu { // Get the disk space data NSArray *diskSpaceData = [diskSpaceMonitor diskSpaceData]; - if (!diskSpaceData || ![diskSpaceData count]) return extraMenu; + if (!diskSpaceData || ![diskSpaceData count]) + return extraMenu; // Build the menu item images NSArray *itemImages = [self diskSpaceMenuItemImages:diskSpaceData]; - if ([itemImages count] != [diskSpaceData count]) return extraMenu; + if ([itemImages count] != [diskSpaceData count]) + return extraMenu; // Add our menu item images for (int i = 0; i < [itemImages count]; i++) { @@ -160,8 +162,8 @@ - (NSMenu *)menu { [item setRepresentedObject:[[diskSpaceData objectAtIndex:i] objectForKey:@"path"]]; [item setTarget:self]; } - [extraMenu addItem:[NSMenuItem separatorItem]]; - [self addStandardMenuEntriesTo:extraMenu]; + [extraMenu addItem:[NSMenuItem separatorItem]]; + [self addStandardMenuEntriesTo:extraMenu]; return extraMenu; @@ -175,22 +177,23 @@ - (NSArray *)diskSpaceMenuItemImages:(NSArray *)driveDetails { // Set up attributes for strings NSDictionary *stringAttributes = [NSDictionary dictionaryWithObjectsAndKeys: - fgMenuThemeColor, - NSForegroundColorAttributeName, - [NSFont monospacedDigitSystemFontOfSize:11.0f weight:NSFontWeightRegular], - NSFontAttributeName, - nil]; + fgMenuThemeColor, + NSForegroundColorAttributeName, + [NSFont monospacedDigitSystemFontOfSize:11.0 + weight:NSFontWeightRegular], + NSFontAttributeName, + nil]; // Loop the disk info, deciding on text metrics and generating // attributed strings - NSMutableArray *nameStrings = [NSMutableArray array], - *detailStrings = [NSMutableArray array], - *freeStrings = [NSMutableArray array], - *usedStrings = [NSMutableArray array], - *totalStrings = [NSMutableArray array]; - double widestNameText = 0, widestDetailsText = 0, - widestFreeSpaceText = 0, widestUsedSpaceText = 0, - widestTotalSpaceText = 0; + NSMutableArray *nameStrings = [NSMutableArray array], + *detailStrings = [NSMutableArray array], + *freeStrings = [NSMutableArray array], + *usedStrings = [NSMutableArray array], + *totalStrings = [NSMutableArray array]; + double widestNameText = 0, widestDetailsText = 0, + widestFreeSpaceText = 0, widestUsedSpaceText = 0, + widestTotalSpaceText = 0; NSEnumerator *driveDetailEnum = [driveDetails objectEnumerator]; NSDictionary *driveDetail = nil; while ((driveDetail = [driveDetailEnum nextObject])) { @@ -198,8 +201,8 @@ - (NSArray *)diskSpaceMenuItemImages:(NSArray *)driveDetails { // Name text renderString = [[NSMutableAttributedString alloc] - initWithString:[driveDetail objectForKey:@"name"]]; - [renderString addAttributes:stringAttributes range:NSMakeRange(0,[renderString length])]; + initWithString:[driveDetail objectForKey:@"name"]]; + [renderString addAttributes:stringAttributes range:NSMakeRange(0, [renderString length])]; [nameStrings addObject:renderString]; if ([renderString size].width > widestNameText) { widestNameText = [renderString size].width; @@ -207,10 +210,10 @@ - (NSArray *)diskSpaceMenuItemImages:(NSArray *)driveDetails { // Details renderString = [[NSMutableAttributedString alloc] - initWithString:[NSString stringWithFormat:@"(%@, %@)", - [driveDetail objectForKey:@"device"], - [driveDetail objectForKey:@"fstype"]]]; - [renderString addAttributes:stringAttributes range:NSMakeRange(0,[renderString length])]; + initWithString:[NSString stringWithFormat:@"(%@, %@)", + [driveDetail objectForKey:@"device"], + [driveDetail objectForKey:@"fstype"]]]; + [renderString addAttributes:stringAttributes range:NSMakeRange(0, [renderString length])]; [detailStrings addObject:renderString]; if ([renderString size].width > widestDetailsText) { widestDetailsText = [renderString size].width; @@ -218,27 +221,26 @@ - (NSArray *)diskSpaceMenuItemImages:(NSArray *)driveDetails { // Now used, free and total renderString = [[NSMutableAttributedString alloc] - initWithString:[driveDetail objectForKey:@"free"]]; - [renderString addAttributes:stringAttributes range:NSMakeRange(0,[renderString length])]; + initWithString:[driveDetail objectForKey:@"free"]]; + [renderString addAttributes:stringAttributes range:NSMakeRange(0, [renderString length])]; [freeStrings addObject:renderString]; if ([renderString size].width > widestFreeSpaceText) { widestFreeSpaceText = [renderString size].width; } renderString = [[NSMutableAttributedString alloc] - initWithString:[driveDetail objectForKey:@"used"]]; - [renderString addAttributes:stringAttributes range:NSMakeRange(0,[renderString length])]; + initWithString:[driveDetail objectForKey:@"used"]]; + [renderString addAttributes:stringAttributes range:NSMakeRange(0, [renderString length])]; [usedStrings addObject:renderString]; if ([renderString size].width > widestUsedSpaceText) { widestUsedSpaceText = [renderString size].width; } renderString = [[NSMutableAttributedString alloc] - initWithString:[driveDetail objectForKey:@"total"]]; - [renderString addAttributes:stringAttributes range:NSMakeRange(0,[renderString length])]; + initWithString:[driveDetail objectForKey:@"total"]]; + [renderString addAttributes:stringAttributes range:NSMakeRange(0, [renderString length])]; [totalStrings addObject:renderString]; if ([renderString size].width > widestTotalSpaceText) { widestTotalSpaceText = [renderString size].width; } - } // Round off the text widths @@ -266,25 +268,25 @@ - (NSArray *)diskSpaceMenuItemImages:(NSArray *)driveDetails { } // Build the new image - NSImage *menuItemImage = [NSImage imageWithSize:NSMakeSize([volIcon size].width + 10 + (float)finalTextWidth, - [volIcon size].height) - flipped:NO - drawingHandler:^BOOL(NSRect dstRect) { - [volIcon compositeToPoint:NSMakePoint(0, 0) operation:NSCompositeSourceOver]; - [(NSAttributedString *)[nameStrings objectAtIndex:i] - drawAtPoint:NSMakePoint(ceilf((float)[volIcon size].width) + 10, - ceilf((float)[volIcon size].height / 2))]; - [(NSAttributedString *)[detailStrings objectAtIndex:i] - drawAtPoint:NSMakePoint(ceilf((float)[volIcon size].width) + 10 + (float)widestNameText + 15, - ceilf((float)[volIcon size].height / 2))]; - [(NSAttributedString *)[usedStrings objectAtIndex:i] - drawAtPoint:NSMakePoint(ceilf((float)[volIcon size].width) + 10, 1)]; - [(NSAttributedString *)[freeStrings objectAtIndex:i] - drawAtPoint:NSMakePoint(ceilf((float)[volIcon size].width) + 10 + (float)widestUsedSpaceText + 10, 1)]; - [(NSAttributedString *)[totalStrings objectAtIndex:i] - drawAtPoint:NSMakePoint(ceilf((float)[volIcon size].width) + 10 + (float)widestUsedSpaceText + 10 + (float)widestFreeSpaceText + 10, 1)]; - return YES; - } ]; + NSImage *menuItemImage = [NSImage imageWithSize:NSMakeSize([volIcon size].width + 10 + finalTextWidth, + [volIcon size].height) + flipped:NO + drawingHandler:^BOOL(NSRect dstRect) { + [volIcon compositeToPoint:NSMakePoint(0, 0) operation:NSCompositeSourceOver]; + [(NSAttributedString *)[nameStrings objectAtIndex:i] + drawAtPoint:NSMakePoint(ceil([volIcon size].width) + 10, + ceil([volIcon size].height / 2))]; + [(NSAttributedString *)[detailStrings objectAtIndex:i] + drawAtPoint:NSMakePoint(ceil([volIcon size].width) + 10 + widestNameText + 15, + ceil([volIcon size].height / 2))]; + [(NSAttributedString *)[usedStrings objectAtIndex:i] + drawAtPoint:NSMakePoint(ceil([volIcon size].width) + 10, 1)]; + [(NSAttributedString *)[freeStrings objectAtIndex:i] + drawAtPoint:NSMakePoint(ceil([volIcon size].width) + 10 + widestUsedSpaceText + 10, 1)]; + [(NSAttributedString *)[totalStrings objectAtIndex:i] + drawAtPoint:NSMakePoint(ceil([volIcon size].width) + 10 + widestUsedSpaceText + 10 + widestFreeSpaceText + 10, 1)]; + return YES; + }]; [itemImages addObject:menuItemImage]; } @@ -294,7 +296,7 @@ - (NSArray *)diskSpaceMenuItemImages:(NSArray *)driveDetails { /////////////////////////////////////////////////////////////// // -// Timer callback +// Timer callback // /////////////////////////////////////////////////////////////// @@ -314,7 +316,7 @@ - (void)timerFired:(NSTimer *)timer { /////////////////////////////////////////////////////////////// // -// Menu actions +// Menu actions // /////////////////////////////////////////////////////////////// @@ -325,7 +327,8 @@ - (void)openOrEjectVolume:(id)sender { // Decide action BOOL eject = ([ourPrefs diskSelectMode] == kDiskSelectModeEject); - if (modKeys & optionKey) eject = !eject; + if (modKeys & optionKey) + eject = !eject; if (eject) { BOOL removable = NO; @@ -341,21 +344,23 @@ - (void)openOrEjectVolume:(id)sender { // both got bizarrely slow in 10.4.x. Wrap in exception handling for NSTask errors, // using old-school for 10.2 compatibility. NS_DURING - if (removable) { - [[NSTask launchedTaskWithLaunchPath:@"/usr/sbin/diskutil" - arguments:[NSArray arrayWithObjects:@"eject", - [sender representedObject], - nil]] waitUntilExit]; - } else { - [[NSTask launchedTaskWithLaunchPath:@"/usr/sbin/diskutil" - arguments:[NSArray arrayWithObjects:@"unmount", - [sender representedObject], - nil]] waitUntilExit]; - } + if (removable) { + [[NSTask launchedTaskWithLaunchPath:@"/usr/sbin/diskutil" + arguments:[NSArray arrayWithObjects:@"eject", + [sender representedObject], + nil]] waitUntilExit]; + } + else { + [[NSTask launchedTaskWithLaunchPath:@"/usr/sbin/diskutil" + arguments:[NSArray arrayWithObjects:@"unmount", + [sender representedObject], + nil]] waitUntilExit]; + } NS_HANDLER - NSLog(@"MenuMeterDisk unable to eject/unmount \"%@\" using diskutil.", [sender representedObject]); + NSLog(@"MenuMeterDisk unable to eject/unmount \"%@\" using diskutil.", [sender representedObject]); NS_ENDHANDLER - } else { + } + else { if (![[NSWorkspace sharedWorkspace] openFile:[sender representedObject]]) { NSLog(@"MenuMeterDisk unable to open \"%@\".", [sender representedObject]); } @@ -365,21 +370,20 @@ - (void)openOrEjectVolume:(id)sender { /////////////////////////////////////////////////////////////// // -// Prefs +// Prefs // /////////////////////////////////////////////////////////////// - (void)configFromPrefs:(NSNotification *)notification { #ifdef ELCAPITAN - [super configDisplay:kDiskMenuBundleID fromPrefs:ourPrefs withTimerInterval:[ourPrefs diskInterval]]; + [super configDisplay:kDiskMenuBundleID + fromPrefs:ourPrefs + withTimerInterval:[ourPrefs diskInterval]]; #endif - // Update prefs - [ourPrefs syncWithDisk]; - // Handle menubar theme changes fgMenuThemeColor = self.menuBarTextColor; - + // Decide on image set name prefix NSString *imageSetNamePrefix = [kDiskImageSets objectAtIndex:[ourPrefs diskImageset]]; if (self.isDark) { @@ -397,8 +401,10 @@ - (void)configFromPrefs:(NSNotification *)notification { writeImage = nil; readwriteImage = nil; + NSBundle *bundle = [NSBundle mainBundle]; + // Setup new images as overlays or basic images - float menubarHeight = self.height; + float menubarHeight = self.height; if ([ourPrefs diskImageset] == kDiskArrowsImageSet) { // Small disk arrow is an overlay on the boot disk icon idleImage = [[NSImage alloc] initWithSize:NSMakeSize(kDiskViewWidth, menubarHeight)]; @@ -411,32 +417,30 @@ - (void)configFromPrefs:(NSNotification *)notification { [readImage lockFocus]; [bootDiskIcon compositeToPoint:NSMakePoint(0, (menubarHeight - kDiskViewWidth) / 2) operation:NSCompositeSourceOver]; - [[[NSImage alloc] initWithContentsOfFile: - [[NSBundle mainBundle] pathForResource:[imageSetNamePrefix stringByAppendingString:@"Read"] - ofType:@"tiff"]] - compositeToPoint:NSMakePoint(0, 0) operation:NSCompositeSourceOver]; + [[bundle imageForResource:[imageSetNamePrefix stringByAppendingString:@"Read"]] + compositeToPoint:NSMakePoint(0, 0) + operation:NSCompositeSourceOver]; [readImage unlockFocus]; // Write writeImage = [[NSImage alloc] initWithSize:NSMakeSize(kDiskViewWidth, menubarHeight)]; [writeImage lockFocus]; [bootDiskIcon compositeToPoint:NSMakePoint(0, (menubarHeight - kDiskViewWidth) / 2) operation:NSCompositeSourceOver]; - [[[NSImage alloc] initWithContentsOfFile: - [[NSBundle mainBundle]pathForResource:[imageSetNamePrefix stringByAppendingString:@"Write"] - ofType:@"tiff"]] - compositeToPoint:NSMakePoint(0, 0) operation:NSCompositeSourceOver]; + [[bundle imageForResource:[imageSetNamePrefix stringByAppendingString:@"Write"]] + compositeToPoint:NSMakePoint(0, 0) + operation:NSCompositeSourceOver]; [writeImage unlockFocus]; // Read/Write readwriteImage = [[NSImage alloc] initWithSize:NSMakeSize(kDiskViewWidth, menubarHeight)]; [readwriteImage lockFocus]; [bootDiskIcon compositeToPoint:NSMakePoint(0, (menubarHeight - kDiskViewWidth) / 2) operation:NSCompositeSourceOver]; - [[[NSImage alloc] initWithContentsOfFile: - [[NSBundle mainBundle]pathForResource:[imageSetNamePrefix stringByAppendingString:@"ReadWrite"] - ofType:@"tiff"]] - compositeToPoint:NSMakePoint(0, 0) operation:NSCompositeSourceOver]; + [[bundle imageForResource:[imageSetNamePrefix stringByAppendingString:@"ReadWrite"]] + compositeToPoint:NSMakePoint(0, 0) + operation:NSCompositeSourceOver]; [readwriteImage unlockFocus]; - } else if ([ourPrefs diskImageset] == kDiskArrowsLargeImageSet) { + } + else if ([ourPrefs diskImageset] == kDiskArrowsLargeImageSet) { // Large arrow disk icon overlays based on patches by Mac-arena the Bored Zo // (macrulez at softhome.net). // Read @@ -469,7 +473,7 @@ - (void)configFromPrefs:(NSNotification *)notification { idleImage = [[NSImage alloc] initWithSize:NSMakeSize(kDiskViewWidth, menubarHeight)]; [idleImage lockFocus]; [bootDiskIcon compositeToPoint:NSMakePoint(0, (menubarHeight - kDiskViewWidth) / 2) - operation:NSCompositeSourceOver]; + operation:NSCompositeSourceOver]; [idleImage unlockFocus]; // Read/Write readwriteImage = [[NSImage alloc] initWithSize:NSMakeSize(kDiskViewWidth, menubarHeight)]; @@ -481,20 +485,17 @@ - (void)configFromPrefs:(NSNotification *)notification { [[NSColor redColor] set]; [writeArrowPath fill]; [readwriteImage unlockFocus]; - } else { + } + else { // Load the static images - idleImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] - pathForResource:[imageSetNamePrefix stringByAppendingString:@"Idle"] ofType:@"tiff"]]; - readImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] - pathForResource:[imageSetNamePrefix stringByAppendingString:@"Read"] ofType:@"tiff"]]; - writeImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] - pathForResource:[imageSetNamePrefix stringByAppendingString:@"Write"] ofType:@"tiff"]]; - readwriteImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] - pathForResource:[imageSetNamePrefix stringByAppendingString:@"ReadWrite"] ofType:@"tiff"]]; + idleImage = [bundle imageForResource:[imageSetNamePrefix stringByAppendingString:@"Idle"]]; + readImage = [bundle imageForResource:[imageSetNamePrefix stringByAppendingString:@"Read"]]; + writeImage = [bundle imageForResource:[imageSetNamePrefix stringByAppendingString:@"Write"]]; + readwriteImage = [bundle imageForResource:[imageSetNamePrefix stringByAppendingString:@"ReadWrite"]]; } // Force initial update - statusItem.button.image=self.image; + statusItem.button.image = self.image; } // configFromPrefs @end diff --git a/MenuExtras/MenuMeterDisk/MenuMeterDiskIO.h b/MenuExtras/MenuMeterDisk/MenuMeterDiskIO.h index 6fa5c822..0f1c290b 100644 --- a/MenuExtras/MenuMeterDisk/MenuMeterDiskIO.h +++ b/MenuExtras/MenuMeterDisk/MenuMeterDiskIO.h @@ -1,50 +1,50 @@ // // MenuMeterDiskIO.h // -// Reader object for disk IO statistics +// Reader object for disk IO statistics // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // +#import "MenuMeterDisk.h" +#import "MenuMeters.h" #import -#import -#import #import #import -#import "MenuMeters.h" -#import "MenuMeterDisk.h" - +#import +#import @interface MenuMeterDiskIO : NSObject { // IOKit connection - mach_port_t masterPort; - IONotificationPortRef notifyPort; - CFRunLoopSourceRef notifyRunSource; - io_iterator_t blockDevicePublishedIterator, - blockDeviceTerminatedIterator, - blockDeviceIterator; + mach_port_t masterPort; + IONotificationPortRef notifyPort; + CFRunLoopSourceRef notifyRunSource; + io_iterator_t blockDevicePublishedIterator, + blockDeviceTerminatedIterator, + blockDeviceIterator; // Tracking values - uint64_t previousTotalRead, previousTotalWrite; + uint64_t previousTotalRead, previousTotalWrite; } // MenuMeterDiskIO // Disk activity info + - (DiskIOActivityType)diskIOActivity; @end diff --git a/MenuExtras/MenuMeterDisk/MenuMeterDiskIO.m b/MenuExtras/MenuMeterDisk/MenuMeterDiskIO.m index a16b2d97..ab4064fb 100644 --- a/MenuExtras/MenuMeterDisk/MenuMeterDiskIO.m +++ b/MenuExtras/MenuMeterDisk/MenuMeterDiskIO.m @@ -1,62 +1,62 @@ // // MenuMeterDiskIO.m // -// Reader object for disk IO statistics +// Reader object for disk IO statistics // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #import "MenuMeterDiskIO.h" #import - /////////////////////////////////////////////////////////////// // -// Private methods and constants +// Private methods and constants // /////////////////////////////////////////////////////////////// @interface MenuMeterDiskIO (PrivateMethods) --(void)blockDeviceChanged:(io_iterator_t)iterator; + +- (void)blockDeviceChanged:(io_iterator_t)iterator; @end /////////////////////////////////////////////////////////////// // -// IOKit notification callbacks +// IOKit notification callbacks // /////////////////////////////////////////////////////////////// static void BlockDeviceChanged(void *ref, io_iterator_t iterator) { - if (ref) [(__bridge MenuMeterDiskIO *)ref blockDeviceChanged:iterator]; + if (ref) + [(__bridge MenuMeterDiskIO *)ref blockDeviceChanged:iterator]; } // BlockDeviceChanged - /////////////////////////////////////////////////////////////// // -// init/dealloc +// init/dealloc // /////////////////////////////////////////////////////////////// @implementation MenuMeterDiskIO -- (id)init { +- (instancetype)init { self = [super init]; if (!self) { @@ -79,7 +79,7 @@ - (id)init { CFRunLoopAddSource(CFRunLoopGetCurrent(), notifyRunSource, kCFRunLoopDefaultMode); // Install notifications for block storage devices - err = IOServiceAddMatchingNotification(notifyPort, kIOPublishNotification, + err = IOServiceAddMatchingNotification(notifyPort, kIOPublishNotification, IOServiceMatching(kIOBlockStorageDriverClass), BlockDeviceChanged, (__bridge void *)(self), &blockDevicePublishedIterator); if (err != KERN_SUCCESS) { @@ -105,20 +105,25 @@ - (id)init { - (void)dealloc { - if (blockDeviceIterator) IOObjectRelease(blockDeviceIterator); - if (blockDevicePublishedIterator) IOObjectRelease(blockDevicePublishedIterator); - if (blockDeviceTerminatedIterator) IOObjectRelease(blockDeviceTerminatedIterator); + if (blockDeviceIterator) + IOObjectRelease(blockDeviceIterator); + if (blockDevicePublishedIterator) + IOObjectRelease(blockDevicePublishedIterator); + if (blockDeviceTerminatedIterator) + IOObjectRelease(blockDeviceTerminatedIterator); if (notifyRunSource) { CFRunLoopRemoveSource(CFRunLoopGetCurrent(), notifyRunSource, kCFRunLoopDefaultMode); } - if (notifyPort) IONotificationPortDestroy(notifyPort); - if (masterPort) mach_port_deallocate(mach_task_self(), masterPort); + if (notifyPort) + IONotificationPortDestroy(notifyPort); + if (masterPort) + mach_port_deallocate(mach_task_self(), masterPort); } // dealloc /////////////////////////////////////////////////////////////// // -// Disk activity +// Disk activity // /////////////////////////////////////////////////////////////// @@ -130,7 +135,7 @@ - (DiskIOActivityType)diskIOActivity { IOServiceMatching(kIOBlockStorageDriverClass), &blockDeviceIterator); if (err != KERN_SUCCESS) { - return kDiskActivityIdle; // Best we can do + return kDiskActivityIdle; // Best we can do } } @@ -140,22 +145,22 @@ - (DiskIOActivityType)diskIOActivity { uint64_t totalRead = 0, totalWrite = 0; while ((driveEntry = IOIteratorNext(blockDeviceIterator))) { - // Get the statistics for this drive - NSDictionary* statistics = CFBridgingRelease(IORegistryEntryCreateCFProperty(driveEntry, - CFSTR(kIOBlockStorageDriverStatisticsKey), - kCFAllocatorDefault, - kNilOptions)); + // Get the statistics for this drive + NSDictionary *statistics = CFBridgingRelease(IORegistryEntryCreateCFProperty(driveEntry, + CFSTR(kIOBlockStorageDriverStatisticsKey), + kCFAllocatorDefault, + kNilOptions)); // If we got the statistics block for this device then we can add it to our totals if (statistics) { // Get total bytes read NSNumber *statNumber = (NSNumber *)[statistics objectForKey: - (NSString *)CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey)]; + (NSString *)CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey)]; if (statNumber) { totalRead += [statNumber unsignedLongLongValue]; } // Bytes written statNumber = (NSNumber *)[statistics objectForKey: - (NSString *)CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey)]; + (NSString *)CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey)]; if (statNumber) { totalWrite += [statNumber unsignedLongLongValue]; } @@ -178,9 +183,11 @@ - (DiskIOActivityType)diskIOActivity { DiskIOActivityType activity = kDiskActivityIdle; if ((totalRead != previousTotalRead) && (totalWrite != previousTotalWrite)) { activity = kDiskActivityReadWrite; - } else if (totalRead != previousTotalRead) { + } + else if (totalRead != previousTotalRead) { activity = kDiskActivityRead; - } else if (totalWrite != previousTotalWrite) { + } + else if (totalWrite != previousTotalWrite) { activity = kDiskActivityWrite; } previousTotalRead = totalRead; @@ -191,14 +198,15 @@ - (DiskIOActivityType)diskIOActivity { /////////////////////////////////////////////////////////////// // -// Device state changes +// Device state changes // /////////////////////////////////////////////////////////////// --(void)blockDeviceChanged:(io_iterator_t)iterator { +- (void)blockDeviceChanged:(io_iterator_t)iterator { // Remove the current drive iterator, forcing its recreation later - if (blockDeviceIterator) IOObjectRelease(blockDeviceIterator); + if (blockDeviceIterator) + IOObjectRelease(blockDeviceIterator); blockDeviceIterator = MACH_PORT_NULL; // Drain the iterator diff --git a/MenuExtras/MenuMeterDisk/MenuMeterDiskSpace.h b/MenuExtras/MenuMeterDisk/MenuMeterDiskSpace.h index 091c3f1a..c13eddcb 100644 --- a/MenuExtras/MenuMeterDisk/MenuMeterDiskSpace.h +++ b/MenuExtras/MenuMeterDisk/MenuMeterDiskSpace.h @@ -1,44 +1,46 @@ // // MenuMeterDiskSpace.h // -// Reader object for disk space statistics +// Reader object for disk space statistics // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -#import +#import "LocalizedStrings.h" #import -#import +#import +#import #import +#import #import -#import -#import "LocalizedStrings.h" @interface MenuMeterDiskSpace : NSObject { // NSFormatter for disk space localization - NSNumberFormatter *spaceFormatter; - BOOL useBaseTen; + NSNumberFormatter *spaceFormatter; + BOOL useBaseTen; } // MenuMeterDiskSpace // Disk space info + - (NSMutableArray *)diskSpaceData; + - (void)setBaseTen:(BOOL)baseTen; @end diff --git a/MenuExtras/MenuMeterDisk/MenuMeterDiskSpace.m b/MenuExtras/MenuMeterDisk/MenuMeterDiskSpace.m index 26c78d03..5ab55854 100644 --- a/MenuExtras/MenuMeterDisk/MenuMeterDiskSpace.m +++ b/MenuExtras/MenuMeterDisk/MenuMeterDiskSpace.m @@ -1,77 +1,73 @@ // // MenuMeterDiskSpace.m // -// Reader object for disk space statistics +// Reader object for disk space statistics // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #import "MenuMeterDiskSpace.h" - /////////////////////////////////////////////////////////////// // -// Private methods and functions +// Private methods and functions // /////////////////////////////////////////////////////////////// @interface MenuMeterDiskSpace (PrivateMethods) + - (NSString *)spaceString:(float)space; @end - static NSComparisonResult SortDiskEntryByDeviceString(NSDictionary *a, NSDictionary *b, void *context) { return [(NSString *)[a objectForKey:@"device"] compare:[b objectForKey:@"device"]]; } // SortDiskEntryByDeviceString - /////////////////////////////////////////////////////////////// // -// Localized strings +// Localized strings // /////////////////////////////////////////////////////////////// -#define kUsedSpaceFormat @"%@ Used" -#define kFreeSpaceFormat @"%@ Free" -#define kTotalSpaceFormat @"%@ Total" -#define kKBLabel @"KB" -#define kMBLabel @"MB" -#define kGBLabel @"GB" - +#define kUsedSpaceFormat @"%@ Used" +#define kFreeSpaceFormat @"%@ Free" +#define kTotalSpaceFormat @"%@ Total" +#define kKBLabel @"KB" +#define kMBLabel @"MB" +#define kGBLabel @"GB" /////////////////////////////////////////////////////////////// // -// init/dealloc +// init/dealloc // /////////////////////////////////////////////////////////////// @implementation MenuMeterDiskSpace -- (id)init { +- (instancetype)init { self = [super init]; if (!self) { return nil; } - // Set up a NumberFormatter for localization. This is based on code contributed by Mike Fischer // (mike.fischer at fi-works.de) for use in MenuMeters. NSNumberFormatter *tempFormat = [[NSNumberFormatter alloc] init]; @@ -88,11 +84,11 @@ - (id)init { } // init - // dealloc +// dealloc /////////////////////////////////////////////////////////////// // -// Disk space info +// Disk space info // /////////////////////////////////////////////////////////////// @@ -112,8 +108,8 @@ - (NSMutableArray *)diskSpaceData { for (int i = 0; i < mountCount; i++) { // We only view local volumes, which isn't easy (are FUSE volumes local?) // Just look at filesystem type. - if(!strcmp(mountInfo[i].f_fstypename, "hfs") || - !strcmp(mountInfo[i].f_fstypename, "apfs") || + if (!strcmp(mountInfo[i].f_fstypename, "hfs") || + !strcmp(mountInfo[i].f_fstypename, "apfs") || !strcmp(mountInfo[i].f_fstypename, "ufs") || !strcmp(mountInfo[i].f_fstypename, "msdos") || !strcmp(mountInfo[i].f_fstypename, "exfat") || @@ -127,8 +123,8 @@ - (NSMutableArray *)diskSpaceData { // Build a NSString from the path NSString *mountPath = [[NSFileManager defaultManager] - stringWithFileSystemRepresentation:mountInfo[i].f_mntonname - length:strlen(mountInfo[i].f_mntonname)]; + stringWithFileSystemRepresentation:mountInfo[i].f_mntonname + length:strlen(mountInfo[i].f_mntonname)]; // NSFileManger used to report stale volume names and many other // bugs. Again, probably fixed in new OS versions, but stick with @@ -173,20 +169,21 @@ - (NSMutableArray *)diskSpaceData { // Store [diskStats setObject:[NSString stringWithFormat:[localizedStrings objectForKey:kTotalSpaceFormat], - [self spaceString:((float)mountInfo[i].f_blocks * (float)mountInfo[i].f_bsize)]] + [self spaceString:(float)(mountInfo[i].f_blocks * mountInfo[i].f_bsize)]] forKey:@"total"]; [diskStats setObject:[NSString stringWithFormat:[localizedStrings objectForKey:kFreeSpaceFormat], - [self spaceString:((float)mountInfo[i].f_bavail * (float)mountInfo[i].f_bsize)]] + [self spaceString:(float)(mountInfo[i].f_bavail * mountInfo[i].f_bsize)]] forKey:@"free"]; [diskStats setObject:[NSString stringWithFormat:[localizedStrings objectForKey:kUsedSpaceFormat], - [self spaceString:(((float)mountInfo[i].f_blocks - - (float)mountInfo[i].f_bavail) * (float)mountInfo[i].f_bsize)]] + [self spaceString:(float)((mountInfo[i].f_blocks - + mountInfo[i].f_bavail) * + mountInfo[i].f_bsize)]] forKey:@"used"]; // Store the data into the array [diskSpaceDetails addObject:diskStats]; - } // end of filesystem type check - } // end of mount loop + } // end of filesystem type check + } // end of mount loop // Sort by device, this matches most users expectations best [diskSpaceDetails sortUsingFunction:&SortDiskEntryByDeviceString context:NULL]; @@ -204,7 +201,7 @@ - (void)setBaseTen:(BOOL)baseTen { /////////////////////////////////////////////////////////////// // -// Utility +// Utility // /////////////////////////////////////////////////////////////// @@ -213,30 +210,35 @@ - (NSString *)spaceString:(float)space { if (useBaseTen) { if (space > 1000000000) { return [NSString stringWithFormat:@"%@%@", - [spaceFormatter stringForObjectValue:[NSNumber numberWithFloat:space / 1000000000]], - [localizedStrings objectForKey:kGBLabel]]; - } else if (space > 1000000) { + [spaceFormatter stringForObjectValue:[NSNumber numberWithFloat:space / 1000000000]], + [localizedStrings objectForKey:kGBLabel]]; + } + else if (space > 1000000) { return [NSString stringWithFormat:@"%@%@", - [spaceFormatter stringForObjectValue:[NSNumber numberWithFloat:space / 1000000]], - [localizedStrings objectForKey:kMBLabel]]; - } else { + [spaceFormatter stringForObjectValue:[NSNumber numberWithFloat:space / 1000000]], + [localizedStrings objectForKey:kMBLabel]]; + } + else { return [NSString stringWithFormat:@"%@%@", - [spaceFormatter stringForObjectValue:[NSNumber numberWithFloat:space / 1000]], - [localizedStrings objectForKey:kKBLabel]]; + [spaceFormatter stringForObjectValue:[NSNumber numberWithFloat:space / 1000]], + [localizedStrings objectForKey:kKBLabel]]; } - } else { + } + else { if (space > 1073741824) { return [NSString stringWithFormat:@"%@%@", - [spaceFormatter stringForObjectValue:[NSNumber numberWithFloat:space / 1073741824]], - [localizedStrings objectForKey:kGBLabel]]; - } else if (space > 1048576) { + [spaceFormatter stringForObjectValue:[NSNumber numberWithFloat:space / 1073741824]], + [localizedStrings objectForKey:kGBLabel]]; + } + else if (space > 1048576) { return [NSString stringWithFormat:@"%@%@", - [spaceFormatter stringForObjectValue:[NSNumber numberWithFloat:space / 1048576]], - [localizedStrings objectForKey:kMBLabel]]; - } else { + [spaceFormatter stringForObjectValue:[NSNumber numberWithFloat:space / 1048576]], + [localizedStrings objectForKey:kMBLabel]]; + } + else { return [NSString stringWithFormat:@"%@%@", - [spaceFormatter stringForObjectValue:[NSNumber numberWithFloat:space / 1024]], - [localizedStrings objectForKey:kKBLabel]]; + [spaceFormatter stringForObjectValue:[NSNumber numberWithFloat:space / 1024]], + [localizedStrings objectForKey:kKBLabel]]; } } diff --git a/MenuExtras/MenuMeterMem/MenuMeterMemExtra.h b/MenuExtras/MenuMeterMem/MenuMeterMemExtra.h index bce39172..f41d16ef 100644 --- a/MenuExtras/MenuMeterMem/MenuMeterMemExtra.h +++ b/MenuExtras/MenuMeterMem/MenuMeterMemExtra.h @@ -1,63 +1,62 @@ // // MenuMeterMemExtra.h // -// Menu Extra implementation +// Menu Extra implementation // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -#import -#import -#import "MenuMeters.h" #import "MenuMeterDefaults.h" #import "MenuMeterMem.h" #import "MenuMeterMemStats.h" #import "MenuMeterWorkarounds.h" +#import "MenuMeters.h" +#import +#import - -@interface MenuMeterMemExtra : NSMenuExtra { +@interface MenuMeterMemExtra : NSMenuExtra { // Menu Extra necessities - NSMenu *extraMenu; + NSMenu *extraMenu; // Pref object - MenuMeterDefaults *ourPrefs; + MenuMeterDefaults *ourPrefs; // Info gathers - MenuMeterMemStats *memStats; + MenuMeterMemStats *memStats; // Formatters for numbers so we get localization correctly - NSNumberFormatter *memFloatMBFormatter, - *memIntMBFormatter, - *prettyIntFormatter, - *percentFormatter; + NSNumberFormatter *memFloatMBFormatter, + *memIntMBFormatter, + *prettyIntFormatter, + *percentFormatter; // Colors - NSColor *freeColor, *usedColor, - *activeColor, *inactiveColor, *wireColor, *compressedColor, - *pageInColor, *pageOutColor; + NSColor *freeColor, *usedColor, + *activeColor, *inactiveColor, *wireColor, *compressedColor, + *pageInColor, *pageOutColor; // Image cache for numbers label - NSImage *numberLabelPrerender; + NSImage *numberLabelPrerender; // Width of the menu item - float menuWidth; + float menuWidth; // Width of the text display - float textWidth; + float textWidth; // History data - NSMutableArray *memHistory; - NSDictionary *currentSwapStats; + NSMutableArray *memHistory; + NSDictionary *currentSwapStats; // Theme support - NSColor *fgMenuThemeColor; + NSColor *fgMenuThemeColor; } // MenuMeterMemExtra diff --git a/MenuExtras/MenuMeterMem/MenuMeterMemExtra.m b/MenuExtras/MenuMeterMem/MenuMeterMemExtra.m index 4cb22d02..3b392528 100644 --- a/MenuExtras/MenuMeterMem/MenuMeterMemExtra.m +++ b/MenuExtras/MenuMeterMem/MenuMeterMemExtra.m @@ -1,105 +1,113 @@ // // MenuMeterMemExtra.m // -// Menu Extra implementation +// Menu Extra implementation // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #import "MenuMeterMemExtra.h" - /////////////////////////////////////////////////////////////// // -// Private methods +// Private methods // /////////////////////////////////////////////////////////////// @interface MenuMeterMemExtra (PrivateMethods) // Menu generation + - (void)updateMenuContent; // Image renderers -- (void)renderPieIntoImage:(NSImage *)image; -- (void)renderNumbersIntoImage:(NSImage *)image; -- (void)renderBarIntoImage:(NSImage *)image; -- (void)renderPressureBar:(NSImage *)image; -- (void)renderMemHistoryIntoImage:(NSImage *)image; -- (void)renderPageIndicatorIntoImage:(NSImage *)image; + +- (void)renderPieImageSize:(NSSize)imageSize; + +- (void)renderNumbersImageSize:(NSSize)imageSize; + +- (void)renderBarImageSize:(NSSize)imageSize; + +- (void)renderPressureBarImageSize:(NSSize)imageSize; + +- (void)renderMemHistoryImageSize:(NSSize)imageSize; + +- (void)renderPageIndicatorImageSize:(NSSize)imageSize; // Timer callbacks + - (void)updateMenuWhenDown; // Prefs + - (void)configFromPrefs:(NSNotification *)notification; @end /////////////////////////////////////////////////////////////// // -// Localized strings +// Localized strings // /////////////////////////////////////////////////////////////// -#define kFreeLabel @"F:" -#define kUsedLabel @"U:" -#define kUsageTitle @"Memory Usage:" -#define kPageStatsTitle @"Memory Pages:" -#define kVMStatsTitle @"VM Statistics:" -#define kMemPressureTitle @"Memory Pressure:" -#define kMemPressureFormat @"%@%%\t(level %@)" -#define kSwapStatsTitle @"Swap Files:" -#define kUsageFormat @"%@ used, %@ free, %@ total" -#define kActiveWiredFormat @"%@ active, %@ wired" -#define kInactiveFreeFormat @"%@ inactive, %@ free" -#define kCompressedFormat @"%@ compressed (%@)" -#define kVMPagingFormat @"%@ pageins, %@ pageouts" -#define kVMCacheFormat @"%@ cache lookups, %@ cache hits (%@)" -#define kVMFaultCopyOnWriteFormat @"%@ page faults, %@ copy-on-writes" -#define kSingleSwapFormat @"%@ swap file present in %@" -#define kMultiSwapFormat @"%@ swap files present in %@" -#define kSingleEncryptedSwapFormat @"%@ encrypted swap file present in %@" -#define kMultiEncryptedSwapFormat @"%@ encrypted swap files present in %@" -#define kMaxSingleSwapFormat @"%@ swap file at peak usage" -#define kMaxMultiSwapFormat @"%@ swap files at peak usage" -#define kSwapSizeFormat @"%@ total swap space" -#define kSwapSizeUsedFormat @"%@ total swap space (%@ used)" -#define kMBLabel @"MB" +#define kFreeLabel @"F:" +#define kUsedLabel @"U:" +#define kUsageTitle @"Memory Usage:" +#define kPageStatsTitle @"Memory Pages:" +#define kVMStatsTitle @"VM Statistics:" +#define kMemPressureTitle @"Memory Pressure:" +#define kMemPressureFormat @"%@%%\t(level %@)" +#define kSwapStatsTitle @"Swap Files:" +#define kUsageFormat @"%@ used, %@ free, %@ total" +#define kActiveWiredFormat @"%@ active, %@ wired" +#define kInactiveFreeFormat @"%@ inactive, %@ free" +#define kCompressedFormat @"%@ compressed (%@)" +#define kVMPagingFormat @"%@ pageins, %@ pageouts" +#define kVMCacheFormat @"%@ cache lookups, %@ cache hits (%@)" +#define kVMFaultCopyOnWriteFormat @"%@ page faults, %@ copy-on-writes" +#define kSingleSwapFormat @"%@ swap file present in %@" +#define kMultiSwapFormat @"%@ swap files present in %@" +#define kSingleEncryptedSwapFormat @"%@ encrypted swap file present in %@" +#define kMultiEncryptedSwapFormat @"%@ encrypted swap files present in %@" +#define kMaxSingleSwapFormat @"%@ swap file at peak usage" +#define kMaxMultiSwapFormat @"%@ swap files at peak usage" +#define kSwapSizeFormat @"%@ total swap space" +#define kSwapSizeUsedFormat @"%@ total swap space (%@ used)" +#define kMBLabel @"MB" /////////////////////////////////////////////////////////////// // -// init/unload/dealloc +// init/unload/dealloc // /////////////////////////////////////////////////////////////// @implementation MenuMeterMemExtra -- init { +- (instancetype)init { - self = [super initWithBundleID:kMemMenuBundleID]; - NSBundle*bundle=[NSBundle mainBundle]; + self = [super initWithBundleID:kMemMenuBundleID]; + NSBundle *bundle = [NSBundle mainBundle]; if (!self) { return nil; } - ourPrefs = [MenuMeterDefaults sharedMenuMeterDefaults]; - if (!ourPrefs) { + ourPrefs = [MenuMeterDefaults sharedMenuMeterDefaults]; + if (!ourPrefs) { NSLog(@"MenuMeterMem unable to connect to preferences. Abort."); return nil; } @@ -155,13 +163,13 @@ @implementation MenuMeterMemExtra menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:@"" action:nil keyEquivalent:@""]; [menuItem setEnabled:NO]; - // add items for memory pressure - menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:[bundle localizedStringForKey:kMemPressureTitle value:nil table:nil] - action:nil - keyEquivalent:@""]; - [menuItem setEnabled:NO]; - menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:@"" action:nil keyEquivalent:@""]; - [menuItem setEnabled:NO]; + // add items for memory pressure + menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:[bundle localizedStringForKey:kMemPressureTitle value:nil table:nil] + action:nil + keyEquivalent:@""]; + [menuItem setEnabled:NO]; + menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:@"" action:nil keyEquivalent:@""]; + [menuItem setEnabled:NO]; // Swap file stats menu item and placeholders menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:[bundle localizedStringForKey:kSwapStatsTitle value:nil table:nil] @@ -174,10 +182,8 @@ @implementation MenuMeterMemExtra [menuItem setEnabled:NO]; menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:@"" action:nil keyEquivalent:@""]; [menuItem setEnabled:NO]; - [extraMenu addItem:[NSMenuItem separatorItem]]; - [self addStandardMenuEntriesTo:extraMenu]; - - + [extraMenu addItem:[NSMenuItem separatorItem]]; + [self addStandardMenuEntriesTo:extraMenu]; // Set up a NumberFormatter for localization. This is based on code contributed by Mike Fischer // (mike.fischer at fi-works.de) for use in MenuMeters. @@ -197,60 +203,65 @@ @implementation MenuMeterMemExtra return nil; } - // And configure directly from prefs on first load [self configFromPrefs:nil]; - // And hand ourself back to SystemUIServer + // And hand ourself back to SystemUIServer NSLog(@"MenuMeterMem loaded."); - return self; + return self; } // initWithBundle - // dealloc +// dealloc /////////////////////////////////////////////////////////////// // -// NSMenuExtra view callbacks +// NSMenuExtra view callbacks // /////////////////////////////////////////////////////////////// - (NSImage *)image { - [self setupAppearance]; - - // Image to render into (and return to view) - NSImage *currentImage = [[NSImage alloc] initWithSize:NSMakeSize(menuWidth, - self.height - 1)]; // Don't render without data - if (![memHistory count]) return nil; + if (![memHistory count]) + return nil; - switch ([ourPrefs memDisplayMode]) { - case kMemDisplayPie: - [self renderPieIntoImage:currentImage]; - break; - case kMemDisplayNumber: - [self renderNumbersIntoImage:currentImage]; - break; - case kMemDisplayBar: - if ([ourPrefs memPressure] == true) { - [self renderPressureBar:currentImage]; - } - else { - [self renderBarIntoImage:currentImage]; - } - break; - case kMemDisplayGraph: - if([ourPrefs memPressure]){ - [self renderPressureHistoryIntoImage:currentImage]; - }else{ - [self renderMemHistoryIntoImage:currentImage]; - } - } - if ([ourPrefs memPageIndicator]) { - [self renderPageIndicatorIntoImage:currentImage]; - } + [self setupAppearance]; + NSSize imageSize = NSMakeSize(menuWidth, self.height - 1); + // Image to render into (and return to view) + MenuMeterDefaults *prefs = ourPrefs; + NSImage *currentImage = [NSImage imageWithSize:imageSize + flipped:NO + drawingHandler:^BOOL(NSRect dstRect) { + switch ([prefs memDisplayMode]) { + case kMemDisplayPie: + [self renderPieImageSize:imageSize]; + break; + case kMemDisplayNumber: + [self renderNumbersImageSize:imageSize]; + break; + case kMemDisplayBar: + if ([prefs memPressure]) { + [self renderPressureBarImageSize:imageSize]; + } + else { + [self renderBarImageSize:imageSize]; + } + break; + case kMemDisplayGraph: + if ([prefs memPressure]) { + [self renderPressureHistoryImageSize:imageSize]; + } + else { + [self renderMemHistoryImageSize:imageSize]; + } + } + if ([prefs memPageIndicator]) { + [self renderPageIndicatorImageSize:imageSize]; + } + return YES; + }]; // Send it back for the view to render return currentImage; @@ -266,7 +277,8 @@ - (NSMenu *)menu { if ([memHistory count] >= [ourPrefs memGraphLength]) { [memHistory removeObjectsInRange:NSMakeRange(0, [memHistory count] - [ourPrefs memGraphLength] + 1)]; } - } else { + } + else { [memHistory removeAllObjects]; } [memHistory addObject:currentStats]; @@ -286,7 +298,7 @@ - (NSMenu *)menu { /////////////////////////////////////////////////////////////// // -// Menu generation +// Menu generation // /////////////////////////////////////////////////////////////// @@ -299,104 +311,99 @@ - (NSMenu *)menu { // called the menu method directly. - (void)updateMenuContent { - NSString *title = nil; + NSString *title = nil; // Fetch stats NSDictionary *currentMemStats = [memHistory objectAtIndex:0]; - if (!(currentMemStats && currentSwapStats)) return; + if (!(currentMemStats && currentSwapStats)) + return; // Usage title = [NSString stringWithFormat:kMenuIndentFormat, - [NSString stringWithFormat:[localizedStrings objectForKey:kUsageFormat], - [memFloatMBFormatter stringForObjectValue:[currentMemStats objectForKey:@"usedmb"]], - [memFloatMBFormatter stringForObjectValue:[currentMemStats objectForKey:@"freemb"]], - [memIntMBFormatter stringForObjectValue:[currentMemStats objectForKey:@"totalmb"]]]]; + [NSString stringWithFormat:[localizedStrings objectForKey:kUsageFormat], + [memFloatMBFormatter stringForObjectValue:[currentMemStats objectForKey:@"usedmb"]], + [memFloatMBFormatter stringForObjectValue:[currentMemStats objectForKey:@"freemb"]], + [memIntMBFormatter stringForObjectValue:[currentMemStats objectForKey:@"totalmb"]]]]; LiveUpdateMenuItemTitle(extraMenu, kMemUsageInfoMenuIndex, title); // Wired title = [NSString stringWithFormat:kMenuIndentFormat, - [NSString stringWithFormat:[localizedStrings objectForKey:kActiveWiredFormat], - [memFloatMBFormatter stringForObjectValue:[currentMemStats objectForKey:@"activemb"]], - [memFloatMBFormatter stringForObjectValue:[currentMemStats objectForKey:@"wiremb"]]]]; + [NSString stringWithFormat:[localizedStrings objectForKey:kActiveWiredFormat], + [memFloatMBFormatter stringForObjectValue:[currentMemStats objectForKey:@"activemb"]], + [memFloatMBFormatter stringForObjectValue:[currentMemStats objectForKey:@"wiremb"]]]]; LiveUpdateMenuItemTitle(extraMenu, kMemActiveWiredInfoMenuIndex, title); // Inactive/Free title = [NSString stringWithFormat:kMenuIndentFormat, - [NSString stringWithFormat:[localizedStrings objectForKey:kInactiveFreeFormat], - [memFloatMBFormatter stringForObjectValue:[currentMemStats objectForKey:@"inactivemb"]], - [memFloatMBFormatter stringForObjectValue:[currentMemStats objectForKey:@"freepagemb"]]]]; + [NSString stringWithFormat:[localizedStrings objectForKey:kInactiveFreeFormat], + [memFloatMBFormatter stringForObjectValue:[currentMemStats objectForKey:@"inactivemb"]], + [memFloatMBFormatter stringForObjectValue:[currentMemStats objectForKey:@"freepagemb"]]]]; LiveUpdateMenuItemTitle(extraMenu, kMemInactiveFreeInfoMenuIndex, title); // Compressed title = [NSString stringWithFormat:kMenuIndentFormat, - [NSString stringWithFormat:[localizedStrings objectForKey:kCompressedFormat], - [memFloatMBFormatter stringForObjectValue:[currentMemStats objectForKey:@"compressedmb"]], - [memFloatMBFormatter stringForObjectValue:[currentMemStats objectForKey:@"uncompressedmb"]]]]; + [NSString stringWithFormat:[localizedStrings objectForKey:kCompressedFormat], + [memFloatMBFormatter stringForObjectValue:[currentMemStats objectForKey:@"compressedmb"]], + [memFloatMBFormatter stringForObjectValue:[currentMemStats objectForKey:@"uncompressedmb"]]]]; LiveUpdateMenuItemTitle(extraMenu, kMemCompressedInfoMenuIndex, title); // VM paging title = [NSString stringWithFormat:kMenuIndentFormat, - [NSString stringWithFormat:[localizedStrings objectForKey:kVMPagingFormat], - [prettyIntFormatter stringForObjectValue:[currentMemStats objectForKey:@"pageins"]], - [prettyIntFormatter stringForObjectValue:[currentMemStats objectForKey:@"pageouts"]]]]; + [NSString stringWithFormat:[localizedStrings objectForKey:kVMPagingFormat], + [prettyIntFormatter stringForObjectValue:[currentMemStats objectForKey:@"pageins"]], + [prettyIntFormatter stringForObjectValue:[currentMemStats objectForKey:@"pageouts"]]]]; LiveUpdateMenuItemTitle(extraMenu, kMemVMPageInfoMenuIndex, title); // VM cache const double divisor = [[currentMemStats objectForKey:@"lookups"] doubleValue]; title = [NSString stringWithFormat:kMenuIndentFormat, - [NSString stringWithFormat:[localizedStrings objectForKey:kVMCacheFormat], - [prettyIntFormatter stringForObjectValue:[currentMemStats objectForKey:@"lookups"]], - [prettyIntFormatter stringForObjectValue:[currentMemStats objectForKey:@"hits"]], - [percentFormatter stringForObjectValue: - [NSNumber numberWithDouble: - divisor == 0.0 ? 0.0 : - (double)(([[currentMemStats objectForKey:@"hits"] doubleValue] / - divisor) * 100.0)]]]]; + [NSString stringWithFormat:[localizedStrings objectForKey:kVMCacheFormat], + [prettyIntFormatter stringForObjectValue:[currentMemStats objectForKey:@"lookups"]], + [prettyIntFormatter stringForObjectValue:[currentMemStats objectForKey:@"hits"]], + [percentFormatter stringForObjectValue: + [NSNumber numberWithDouble: + divisor == 0.0 ? 0.0 : (double)(([[currentMemStats objectForKey:@"hits"] doubleValue] / divisor) * 100.0)]]]]; LiveUpdateMenuItemTitle(extraMenu, kMemVMCacheInfoMenuIndex, title); // VM fault title = [NSString stringWithFormat:kMenuIndentFormat, - [NSString stringWithFormat:[localizedStrings objectForKey:kVMFaultCopyOnWriteFormat], - [prettyIntFormatter stringForObjectValue:[currentMemStats objectForKey:@"faults"]], - [prettyIntFormatter stringForObjectValue:[currentMemStats objectForKey:@"cowfaults"]]]]; + [NSString stringWithFormat:[localizedStrings objectForKey:kVMFaultCopyOnWriteFormat], + [prettyIntFormatter stringForObjectValue:[currentMemStats objectForKey:@"faults"]], + [prettyIntFormatter stringForObjectValue:[currentMemStats objectForKey:@"cowfaults"]]]]; LiveUpdateMenuItemTitle(extraMenu, kMemVMFaultInfoMenuIndex, title); - - title=[NSString stringWithFormat:kMenuIndentFormat, - [NSString stringWithFormat:[localizedStrings objectForKey:kMemPressureFormat],[currentMemStats objectForKey:@"mempress"],[currentMemStats objectForKey:@"mempresslevel"]]]; - LiveUpdateMenuItemTitle(extraMenu, kMemMemPressureInfoMenuIndex, title); - + + title = [NSString stringWithFormat:kMenuIndentFormat, + [NSString stringWithFormat:[localizedStrings objectForKey:kMemPressureFormat], [currentMemStats objectForKey:@"mempress"], [currentMemStats objectForKey:@"mempresslevel"]]]; + LiveUpdateMenuItemTitle(extraMenu, kMemMemPressureInfoMenuIndex, title); + // Swap count/path, Tiger swap encryptioninfo from Michael Nordmeyer (http://goodyworks.com) if ([[currentSwapStats objectForKey:@"swapencrypted"] boolValue]) { title = [NSString stringWithFormat:kMenuIndentFormat, - [NSString stringWithFormat: - (([[currentSwapStats objectForKey:@"swapcount"] unsignedIntValue] != 1) ? - [localizedStrings objectForKey:kMultiEncryptedSwapFormat] : - [localizedStrings objectForKey:kSingleEncryptedSwapFormat]), - [prettyIntFormatter stringForObjectValue:[currentSwapStats objectForKey:@"swapcount"]], - [currentSwapStats objectForKey:@"swappath"]]]; + [NSString stringWithFormat: + (([[currentSwapStats objectForKey:@"swapcount"] unsignedIntValue] != 1) ? [localizedStrings objectForKey:kMultiEncryptedSwapFormat] : [localizedStrings objectForKey:kSingleEncryptedSwapFormat]), + [prettyIntFormatter stringForObjectValue:[currentSwapStats objectForKey:@"swapcount"]], + [currentSwapStats objectForKey:@"swappath"]]]; } LiveUpdateMenuItemTitle(extraMenu, kMemSwapCountInfoMenuIndex, title); // Swap max title = [NSString stringWithFormat:kMenuIndentFormat, - [NSString stringWithFormat: - (([[currentSwapStats objectForKey:@"swapcountpeak"] unsignedIntValue] != 1) ? - [localizedStrings objectForKey:kMaxMultiSwapFormat] : - [localizedStrings objectForKey:kMaxSingleSwapFormat]), - [prettyIntFormatter stringForObjectValue:[currentSwapStats objectForKey:@"swapcountpeak"]]]]; + [NSString stringWithFormat: + (([[currentSwapStats objectForKey:@"swapcountpeak"] unsignedIntValue] != 1) ? [localizedStrings objectForKey:kMaxMultiSwapFormat] : [localizedStrings objectForKey:kMaxSingleSwapFormat]), + [prettyIntFormatter stringForObjectValue:[currentSwapStats objectForKey:@"swapcountpeak"]]]]; LiveUpdateMenuItemTitle(extraMenu, kMemSwapMaxCountInfoMenuIndex, title); // Swap size, Tiger swap used path from Michael Nordmeyer (http://goodyworks.com) title = [NSString stringWithFormat:kMenuIndentFormat, - [NSString stringWithFormat:[localizedStrings objectForKey:kSwapSizeUsedFormat], - [memIntMBFormatter stringForObjectValue:[currentSwapStats objectForKey:@"swapsizemb"]], - [memIntMBFormatter stringForObjectValue:[currentSwapStats objectForKey:@"swapusedmb"]]]]; + [NSString stringWithFormat:[localizedStrings objectForKey:kSwapSizeUsedFormat], + [memIntMBFormatter stringForObjectValue:[currentSwapStats objectForKey:@"swapsizemb"]], + [memIntMBFormatter stringForObjectValue:[currentSwapStats objectForKey:@"swapusedmb"]]]]; LiveUpdateMenuItemTitle(extraMenu, kMemSwapSizeInfoMenuIndex, title); } // updateMenuContent /////////////////////////////////////////////////////////////// // -// Image renderers +// Image renderers // /////////////////////////////////////////////////////////////// -- (void)renderPieIntoImage:(NSImage *)image { +- (void)renderPieImageSize:(NSSize)imageSize { // Load current stats - float totalMB = 1.0f, activeMB = 0, inactiveMB = 0, wireMB = 0, compressedMB = 0; + float totalMB = 1.0, activeMB = 0, inactiveMB = 0, wireMB = 0, compressedMB = 0; NSDictionary *currentMemStats = [memHistory objectAtIndex:0]; if (currentMemStats) { totalMB = [[currentMemStats objectForKey:@"totalmb"] floatValue]; @@ -405,24 +412,39 @@ - (void)renderPieIntoImage:(NSImage *)image { wireMB = [[currentMemStats objectForKey:@"wiremb"] floatValue]; compressedMB = [[currentMemStats objectForKey:@"compressedmb"] floatValue]; } - if (activeMB < 0) { activeMB = 0; }; - if (inactiveMB < 0) { inactiveMB = 0; }; - if (wireMB < 0) { wireMB = 0; }; - if (compressedMB < 0) { compressedMB = 0; }; - if (activeMB > totalMB) { activeMB = totalMB; }; - if (inactiveMB > totalMB) { inactiveMB = totalMB; }; - if (wireMB > totalMB) { wireMB = totalMB; }; - if (compressedMB > totalMB) { compressedMB = totalMB; }; - - // Lock focus and draw curves around a center - [image lockFocus]; + if (activeMB < 0) { + activeMB = 0; + }; + if (inactiveMB < 0) { + inactiveMB = 0; + }; + if (wireMB < 0) { + wireMB = 0; + }; + if (compressedMB < 0) { + compressedMB = 0; + }; + if (activeMB > totalMB) { + activeMB = totalMB; + }; + if (inactiveMB > totalMB) { + inactiveMB = totalMB; + }; + if (wireMB > totalMB) { + wireMB = totalMB; + }; + if (compressedMB > totalMB) { + compressedMB = totalMB; + }; + + // Draw curves around a center NSBezierPath *renderPath = nil; float totalArc = 0; - NSPoint pieCenter = NSMakePoint(kMemPieDisplayWidth / 2, (float)[image size].height / 2); + NSPoint pieCenter = NSMakePoint(kMemPieDisplayWidth / 2, imageSize.height / 2); // Draw wired renderPath = [NSBezierPath bezierPath]; - [renderPath appendBezierPathWithArcWithCenter:pieCenter + [renderPath appendBezierPathWithArcWithCenter:pieCenter radius:(kMemPieDisplayWidth / 2) startAngle:(360 * totalArc) + 90 endAngle:(360 * (wireMB / totalMB + totalArc)) + 90 @@ -469,26 +491,22 @@ - (void)renderPieIntoImage:(NSImage *)image { totalArc += inactiveMB / totalMB; // Finish arc with the default color - [[fgMenuThemeColor colorWithAlphaComponent:kBorderAlpha] set]; + [[fgMenuThemeColor colorWithAlphaComponent:kBorderAlpha] set]; // Close the circle if needed if (totalArc < 1) { renderPath = [NSBezierPath bezierPath]; [renderPath appendBezierPathWithArcWithCenter:pieCenter - radius:(kMemPieDisplayWidth / 2) - 0.5f // Inset radius slightly + radius:(kMemPieDisplayWidth / 2) - 0.5 // Inset radius slightly startAngle:(360 * totalArc) + 90 endAngle:450 clockwise:NO]; - [renderPath setLineWidth:0.6f]; // Lighter line + [renderPath setLineWidth:0.6]; // Lighter line [renderPath stroke]; } - - // Unlock focus - [image unlockFocus]; - } // renderPieIntoImage -- (void)renderNumbersIntoImage:(NSImage *)image { +- (void)renderNumbersImageSize:(NSSize)imageSize { // Read in the RAM data double freeMB = 0, usedMB = 0; @@ -497,81 +515,84 @@ - (void)renderNumbersIntoImage:(NSImage *)image { freeMB = [[currentMemStats objectForKey:@"freemb"] doubleValue]; usedMB = [[currentMemStats objectForKey:@"usedmb"] doubleValue]; } - if (freeMB < 0) freeMB = 0; - if (usedMB < 0) usedMB = 0; - - // Lock focus - [image lockFocus]; + if (freeMB < 0) + freeMB = 0; + if (usedMB < 0) + usedMB = 0; // Construct strings NSAttributedString *renderUString = [[NSAttributedString alloc] - initWithString:[NSString stringWithFormat:@"%.0f%@", - usedMB, - [localizedStrings objectForKey:kMBLabel]] - attributes:[NSDictionary dictionaryWithObjectsAndKeys: - [NSFont monospacedDigitSystemFontOfSize:9.5f weight:NSFontWeightRegular], NSFontAttributeName, - usedColor, NSForegroundColorAttributeName, - nil]]; + initWithString:[NSString stringWithFormat:@"%.0f%@", + usedMB, + [localizedStrings objectForKey:kMBLabel]] + attributes:[NSDictionary dictionaryWithObjectsAndKeys: + [NSFont monospacedDigitSystemFontOfSize:9.5 + weight:NSFontWeightRegular], + NSFontAttributeName, + usedColor, NSForegroundColorAttributeName, + nil]]; // Construct and draw the free string NSAttributedString *renderFString = [[NSAttributedString alloc] - initWithString:[NSString stringWithFormat:@"%.0f%@", - freeMB, - [localizedStrings objectForKey:kMBLabel]] - attributes:[NSDictionary dictionaryWithObjectsAndKeys: - [NSFont monospacedDigitSystemFontOfSize:9.5f weight:NSFontWeightRegular], NSFontAttributeName, - freeColor, NSForegroundColorAttributeName, - nil]]; + initWithString:[NSString stringWithFormat:@"%.0f%@", + freeMB, + [localizedStrings objectForKey:kMBLabel]] + attributes:[NSDictionary dictionaryWithObjectsAndKeys: + [NSFont monospacedDigitSystemFontOfSize:9.5 + weight:NSFontWeightRegular], + NSFontAttributeName, + freeColor, NSForegroundColorAttributeName, + nil]]; // Draw the prerendered label if ([ourPrefs memUsedFreeLabel]) { - [numberLabelPrerender compositeToPoint:NSMakePoint(0,0) operation:NSCompositeSourceOver]; + [numberLabelPrerender compositeToPoint:NSMakePoint(0, 0) operation:NSCompositeSourceOver]; } // Using NSParagraphStyle to right align clipped weird, so do it manually // No descenders so render lower - [renderUString drawAtPoint:NSMakePoint(textWidth - (float)round([renderUString size].width), - (float)floor([image size].height / 2) - 1)]; - [renderFString drawAtPoint:NSMakePoint(textWidth - (float)round([renderFString size].width), -1)]; + [renderUString drawAtPoint:NSMakePoint(textWidth - round([renderUString size].width), + floor(imageSize.height / 2) - 1)]; + [renderFString drawAtPoint:NSMakePoint(textWidth - round([renderFString size].width), -1)]; +} // renderNumbersIntoImage - // Unlock focus - [image unlockFocus]; +- (void)renderPressureBarImageSize:(NSSize)imageSize { + // Load current stats + float pressure = 0.2; + NSDictionary *currentMemStats = [memHistory objectAtIndex:0]; + if (currentMemStats) { + pressure = [[currentMemStats objectForKey:@"mempress"] intValue] / 100.0; + } -} // renderNumbersIntoImage + if (pressure < 0) { + pressure = 0; + }; + + // Draw + NSRect barFrame = NSMakeRect(0, 0, kMemThermometerDisplayWidth, imageSize.height); + + NSRect pressureRect = barFrame; + pressureRect.size.height *= pressure; + + NSBezierPath *pressurePath = [NSBezierPath bezierPathWithRect:pressureRect]; + + NSBezierPath *framePath = [NSBezierPath bezierPathWithRoundedRect:barFrame xRadius:2 yRadius:2]; + + [NSGraphicsContext saveGraphicsState]; + [framePath addClip]; + [[fgMenuThemeColor colorWithAlphaComponent:0.2] set]; + [framePath fill]; + + [activeColor set]; + [pressurePath fill]; + [NSGraphicsContext restoreGraphicsState]; -- (void)renderPressureBar:(NSImage *)image { - // Load current stats - float pressure = 0.2f; - NSDictionary *currentMemStats = [memHistory objectAtIndex:0]; - if (currentMemStats) { - pressure = [[currentMemStats objectForKey:@"mempress"] intValue] / 100.0f; - } - - if (pressure < 0) { pressure = 0; }; - - // Lock focus and draw - [image lockFocus]; - float thermometerTotalHeight = (float)[image size].height - 3.0f; - - NSBezierPath *pressurePath = [NSBezierPath bezierPathWithRect:NSMakeRect(1.5f, 1.5f, kMemThermometerDisplayWidth - 3, thermometerTotalHeight * pressure)]; - - NSBezierPath *framePath = [NSBezierPath bezierPathWithRect:NSMakeRect(1.5f, 1.5f, kMemThermometerDisplayWidth - 3, thermometerTotalHeight)]; - - [activeColor set]; - [pressurePath fill]; - - [[fgMenuThemeColor colorWithAlphaComponent:kBorderAlpha] set]; - - [framePath stroke]; - - // Reset - [[NSColor blackColor] set]; - [image unlockFocus]; } // Bar mode memory view contributed by Bernhard Baehr -- (void)renderBarIntoImage:(NSImage *)image { + +- (void)renderBarImageSize:(NSSize)imageSize { // Load current stats - float totalMB = 1.0f, activeMB = 0, inactiveMB = 0, wireMB = 0, compressedMB = 0; + float totalMB = 1.0, activeMB = 0, inactiveMB = 0, wireMB = 0, compressedMB = 0; NSDictionary *currentMemStats = [memHistory objectAtIndex:0]; if (currentMemStats) { totalMB = [[currentMemStats objectForKey:@"totalmb"] floatValue]; @@ -580,28 +601,61 @@ - (void)renderBarIntoImage:(NSImage *)image { wireMB = [[currentMemStats objectForKey:@"wiremb"] floatValue]; compressedMB = [[currentMemStats objectForKey:@"compressedmb"] floatValue]; } - if (activeMB < 0) { activeMB = 0; }; - if (inactiveMB < 0) { inactiveMB = 0; }; - if (wireMB < 0) { wireMB = 0; }; - if (compressedMB < 0) { compressedMB = 0; }; - if (activeMB > totalMB) { activeMB = totalMB; }; - if (inactiveMB > totalMB) { inactiveMB = totalMB; }; - if (wireMB > totalMB) { wireMB = totalMB; }; - if (compressedMB > totalMB) { compressedMB = totalMB; }; - - // Lock focus and draw - [image lockFocus]; - float thermometerTotalHeight = (float)[image size].height - 3.0f; - - NSBezierPath *wirePath = [NSBezierPath bezierPathWithRect:NSMakeRect(1.5f, 1.5f, kMemThermometerDisplayWidth - 3, - thermometerTotalHeight * (wireMB / totalMB))]; - NSBezierPath *activePath = [NSBezierPath bezierPathWithRect:NSMakeRect(1.5f, 1.5f, kMemThermometerDisplayWidth - 3, - thermometerTotalHeight * ((wireMB + activeMB) / totalMB))]; - NSBezierPath *compressedPath = [NSBezierPath bezierPathWithRect:NSMakeRect(1.5f, 1.5f, kMemThermometerDisplayWidth - 3, - thermometerTotalHeight * ((wireMB + activeMB + compressedMB) / totalMB))]; - NSBezierPath *inactivePath = [NSBezierPath bezierPathWithRect:NSMakeRect(1.5f, 1.5f, kMemThermometerDisplayWidth - 3, - thermometerTotalHeight * ((wireMB + activeMB + compressedMB + inactiveMB) / totalMB))]; - NSBezierPath *framePath = [NSBezierPath bezierPathWithRect:NSMakeRect(1.5f, 1.5f, kMemThermometerDisplayWidth - 3, thermometerTotalHeight)]; + if (activeMB < 0) { + activeMB = 0; + }; + if (inactiveMB < 0) { + inactiveMB = 0; + }; + if (wireMB < 0) { + wireMB = 0; + }; + if (compressedMB < 0) { + compressedMB = 0; + }; + if (activeMB > totalMB) { + activeMB = totalMB; + }; + if (inactiveMB > totalMB) { + inactiveMB = totalMB; + }; + if (wireMB > totalMB) { + wireMB = totalMB; + }; + if (compressedMB > totalMB) { + compressedMB = totalMB; + }; + + // Draw + NSRect barFrame = NSMakeRect(0, 0, kMemThermometerDisplayWidth, imageSize.height); + + NSRect wireRect = barFrame; + wireRect.size.height *= wireMB / totalMB; + + NSRect activeRect = barFrame; + activeRect.size.height *= (wireMB + activeMB) / totalMB; + + NSRect compressedRect = barFrame; + compressedRect.size.height *= (wireMB + activeMB + compressedMB) / totalMB; + + NSRect inactiveRect = barFrame; + inactiveRect.size.height *= (wireMB + activeMB + compressedMB + inactiveMB) / totalMB; + + NSBezierPath *wirePath = [NSBezierPath bezierPathWithRect:wireRect]; + + NSBezierPath *activePath = [NSBezierPath bezierPathWithRect:activeRect]; + + NSBezierPath *compressedPath = [NSBezierPath bezierPathWithRect:compressedRect]; + + NSBezierPath *inactivePath = [NSBezierPath bezierPathWithRect:inactiveRect]; + + NSBezierPath *framePath = [NSBezierPath bezierPathWithRoundedRect:barFrame xRadius:2 yRadius:2]; + + [NSGraphicsContext saveGraphicsState]; + [framePath addClip]; + [[fgMenuThemeColor colorWithAlphaComponent:0.2] set]; + [framePath fill]; + [inactiveColor set]; [inactivePath fill]; [compressedColor set]; @@ -610,68 +664,63 @@ - (void)renderBarIntoImage:(NSImage *)image { [activePath fill]; [wireColor set]; [wirePath fill]; - [[fgMenuThemeColor colorWithAlphaComponent:kBorderAlpha] set]; - [framePath stroke]; - - // Reset - [[NSColor blackColor] set]; - [image unlockFocus]; + [NSGraphicsContext restoreGraphicsState]; } // renderBarIntoImage -- (void)renderPressureHistoryIntoImage:(NSImage *)image { - - // Construct paths - NSBezierPath *activePath = [NSBezierPath bezierPath]; +- (void)renderPressureHistoryImageSize:(NSSize)imageSize { - // Position for initial offset - [activePath moveToPoint:NSMakePoint(0, 0)]; - - // Loop over pixels in desired width until we're out of data - int renderPosition = 0; - // Graph height does not include baseline, reserve the space for real data - // since memory usage can never be zero. - float renderHeight = (float)[image size].height; - for (renderPosition = 0; renderPosition < [ourPrefs memGraphLength]; renderPosition++) { - - // No data at this position? - if (renderPosition >= [memHistory count]) break; + // Construct paths + NSBezierPath *activePath = [NSBezierPath bezierPath]; - // Grab data - NSDictionary *memData = [memHistory objectAtIndex:renderPosition]; - if (!memData) continue; - int pressure = [[memData objectForKey:@"mempress"] intValue]; - if (pressure < 0) { pressure = 0; }; - if (pressure > 100) { pressure = 100; }; + // Position for initial offset + [activePath moveToPoint:NSMakePoint(0, 0)]; - // Update paths (adding baseline) - [activePath lineToPoint:NSMakePoint(renderPosition, - pressure / 100.f * renderHeight)]; - } + // Loop over pixels in desired width until we're out of data + int renderPosition = 0; + // Graph height does not include baseline, reserve the space for real data + // since memory usage can never be zero. + float renderHeight = (float)imageSize.height; + for (renderPosition = 0; renderPosition < [ourPrefs memGraphLength]; renderPosition++) { - // Return to lower edge (fill will close the graph) - [activePath lineToPoint:NSMakePoint(renderPosition - 1, 0)]; + // No data at this position? + if (renderPosition >= [memHistory count]) + break; + // Grab data + NSDictionary *memData = [memHistory objectAtIndex:renderPosition]; + if (!memData) + continue; + int pressure = [[memData objectForKey:@"mempress"] intValue]; + if (pressure < 0) { + pressure = 0; + }; + if (pressure > 100) { + pressure = 100; + }; - // Render the graph - [image lockFocus]; - [activeColor set]; - [activePath fill]; + // Update paths (adding baseline) + [activePath lineToPoint:NSMakePoint(renderPosition, + pressure / 100.f * renderHeight)]; + } - // Clean up - [[NSColor blackColor] set]; - [image unlockFocus]; + // Return to lower edge (fill will close the graph) + [activePath lineToPoint:NSMakePoint(renderPosition - 1, 0)]; + // Render the graph + [activeColor set]; + [activePath fill]; } // renderMemHistoryIntoImages -- (void)renderMemHistoryIntoImage:(NSImage *)image { +- (void)renderMemHistoryImageSize:(NSSize)imageSize { // Construct paths - NSBezierPath *wirePath = [NSBezierPath bezierPath]; - NSBezierPath *activePath = [NSBezierPath bezierPath]; - NSBezierPath *compressedPath = [NSBezierPath bezierPath]; - NSBezierPath *inactivePath = [NSBezierPath bezierPath]; - if (!(wirePath && activePath && inactivePath)) return; + NSBezierPath *wirePath = [NSBezierPath bezierPath]; + NSBezierPath *activePath = [NSBezierPath bezierPath]; + NSBezierPath *compressedPath = [NSBezierPath bezierPath]; + NSBezierPath *inactivePath = [NSBezierPath bezierPath]; + if (!(wirePath && activePath && inactivePath)) + return; // Position for initial offset [wirePath moveToPoint:NSMakePoint(0, 0)]; @@ -683,34 +732,52 @@ - (void)renderMemHistoryIntoImage:(NSImage *)image { int renderPosition = 0; // Graph height does not include baseline, reserve the space for real data // since memory usage can never be zero. - float renderHeight = (float)[image size].height; - for (renderPosition = 0; renderPosition < [ourPrefs memGraphLength]; renderPosition++) { + float renderHeight = (float)imageSize.height; + for (renderPosition = 0; renderPosition < [ourPrefs memGraphLength]; renderPosition++) { // No data at this position? - if (renderPosition >= [memHistory count]) break; + if (renderPosition >= [memHistory count]) + break; // Grab data NSDictionary *memData = [memHistory objectAtIndex:renderPosition]; - if (!memData) continue; + if (!memData) + continue; float activeMB = [[memData objectForKey:@"activemb"] floatValue]; float inactiveMB = [[memData objectForKey:@"inactivemb"] floatValue]; float wireMB = [[memData objectForKey:@"wiremb"] floatValue]; float compressedMB = [[memData objectForKey:@"compressedmb"] floatValue]; float totalMB = [[memData objectForKey:@"totalmb"] floatValue]; - if (activeMB < 0) { activeMB = 0; }; - if (inactiveMB < 0) { inactiveMB = 0; }; - if (wireMB < 0) { wireMB = 0; }; - if (compressedMB < 0) { compressedMB = 0; }; - if (activeMB > totalMB) { activeMB = totalMB; }; - if (inactiveMB > totalMB) { inactiveMB = totalMB; }; - if (wireMB > totalMB) { wireMB = totalMB; }; - if (compressedMB > totalMB) { compressedMB = totalMB; }; + if (activeMB < 0) { + activeMB = 0; + }; + if (inactiveMB < 0) { + inactiveMB = 0; + }; + if (wireMB < 0) { + wireMB = 0; + }; + if (compressedMB < 0) { + compressedMB = 0; + }; + if (activeMB > totalMB) { + activeMB = totalMB; + }; + if (inactiveMB > totalMB) { + inactiveMB = totalMB; + }; + if (wireMB > totalMB) { + wireMB = totalMB; + }; + if (compressedMB > totalMB) { + compressedMB = totalMB; + }; // Update paths (adding baseline) [inactivePath lineToPoint:NSMakePoint(renderPosition, (inactiveMB + compressedMB + activeMB + wireMB) > totalMB ? totalMB : ((inactiveMB + compressedMB + activeMB + wireMB) / totalMB) * renderHeight)]; [compressedPath lineToPoint:NSMakePoint(renderPosition, - (compressedMB + activeMB + wireMB) > totalMB ? totalMB : ((compressedMB + activeMB + wireMB) / totalMB) * renderHeight)]; + (compressedMB + activeMB + wireMB) > totalMB ? totalMB : ((compressedMB + activeMB + wireMB) / totalMB) * renderHeight)]; [activePath lineToPoint:NSMakePoint(renderPosition, (activeMB + wireMB) > totalMB ? totalMB : ((activeMB + wireMB) / totalMB) * renderHeight)]; [wirePath lineToPoint:NSMakePoint(renderPosition, @@ -723,9 +790,7 @@ - (void)renderMemHistoryIntoImage:(NSImage *)image { [activePath lineToPoint:NSMakePoint(renderPosition - 1, 0)]; [wirePath lineToPoint:NSMakePoint(renderPosition - 1, 0)]; - // Render the graph - [image lockFocus]; [inactiveColor set]; [inactivePath fill]; [compressedColor set]; @@ -734,16 +799,12 @@ - (void)renderMemHistoryIntoImage:(NSImage *)image { [activePath fill]; [wireColor set]; [wirePath fill]; - - // Clean up - [[NSColor blackColor] set]; - [image unlockFocus]; - } // renderMemHistoryIntoImages // Paging indicator from Bernhard Baehr. Originally an overlay to the bar display, I liked // it so much I broke the display out so it could be used with any mode. -- (void)renderPageIndicatorIntoImage:(NSImage *)image { + +- (void)renderPageIndicatorImageSize:(NSSize)imageSize { // Read in the paging deltas uint64_t pageIns = 0, pageOuts = 0; @@ -753,44 +814,47 @@ - (void)renderPageIndicatorIntoImage:(NSImage *)image { pageOuts = [[currentMemStats objectForKey:@"deltapageouts"] unsignedLongLongValue]; } - // Lock focus and get height - [image lockFocus]; - float indicatorHeight = (float)[image size].height; - + // Get height + float indicatorHeight = imageSize.height; + BOOL darkTheme = self.isDark; // Set up the pageout path NSBezierPath *arrow = [NSBezierPath bezierPath]; - [arrow moveToPoint:NSMakePoint(kMemPagingDisplayWidth / 2.0f + (menuWidth - kMemPagingDisplayWidth) - 0.5f, 1)]; - [arrow lineToPoint:NSMakePoint(kMemPagingDisplayWidth / 2.0f + (menuWidth - kMemPagingDisplayWidth) + 4.5f, 5.0f)]; - [arrow lineToPoint:NSMakePoint(kMemPagingDisplayWidth / 2.0f + (menuWidth - kMemPagingDisplayWidth) - 5.5f, 5.0f)]; + [arrow moveToPoint:NSMakePoint(kMemPagingDisplayWidth / 2.0 + (menuWidth - kMemPagingDisplayWidth) - 0.5, 1)]; + [arrow lineToPoint:NSMakePoint(kMemPagingDisplayWidth / 2.0 + (menuWidth - kMemPagingDisplayWidth) + 4.5, 5.0)]; + [arrow lineToPoint:NSMakePoint(kMemPagingDisplayWidth / 2.0 + (menuWidth - kMemPagingDisplayWidth) - 5.5, 5.0)]; [arrow closePath]; // Draw if (pageIns) { [pageInColor set]; - } else { + } + else { if (darkTheme) { [[NSColor darkGrayColor] set]; - } else { - [[pageInColor colorWithAlphaComponent:0.25f] set]; + } + else { + [[pageInColor colorWithAlphaComponent:0.25] set]; } } [arrow fill]; // Set up the pagein path arrow = [NSBezierPath bezierPath]; - [arrow moveToPoint:NSMakePoint(kMemPagingDisplayWidth / 2.0f + (menuWidth - kMemPagingDisplayWidth) - 0.5f, indicatorHeight - 1)]; - [arrow lineToPoint:NSMakePoint(kMemPagingDisplayWidth / 2.0f + (menuWidth - kMemPagingDisplayWidth) + 4.5f, indicatorHeight - 5.0f)]; - [arrow lineToPoint:NSMakePoint(kMemPagingDisplayWidth / 2.0f + (menuWidth - kMemPagingDisplayWidth) - 5.5f, indicatorHeight - 5.0f)]; + [arrow moveToPoint:NSMakePoint(kMemPagingDisplayWidth / 2.0 + (menuWidth - kMemPagingDisplayWidth) - 0.5, indicatorHeight - 1)]; + [arrow lineToPoint:NSMakePoint(kMemPagingDisplayWidth / 2.0 + (menuWidth - kMemPagingDisplayWidth) + 4.5, indicatorHeight - 5.0)]; + [arrow lineToPoint:NSMakePoint(kMemPagingDisplayWidth / 2.0 + (menuWidth - kMemPagingDisplayWidth) - 5.5, indicatorHeight - 5.0)]; [arrow closePath]; // Draw if (pageOuts) { [pageOutColor set]; - } else { + } + else { if (darkTheme) { [[NSColor darkGrayColor] set]; - } else { - [[pageOutColor colorWithAlphaComponent:0.25f] set]; + } + else { + [[pageOutColor colorWithAlphaComponent:0.25] set]; } } [arrow fill]; @@ -799,44 +863,45 @@ - (void)renderPageIndicatorIntoImage:(NSImage *)image { NSString *countString = nil; if ((pageIns + pageOuts) >= 1000) { countString = @"1k+"; - } else { + } + else { countString = [NSString stringWithFormat:@"%d", (int)(pageIns + pageOuts)]; } NSAttributedString *renderString = [[NSAttributedString alloc] - initWithString:countString - attributes:[NSDictionary dictionaryWithObjectsAndKeys: - [NSFont monospacedDigitSystemFontOfSize:9.5f weight:NSFontWeightRegular], NSFontAttributeName, - fgMenuThemeColor, NSForegroundColorAttributeName, - nil]]; + initWithString:countString + attributes:[NSDictionary dictionaryWithObjectsAndKeys: + [NSFont monospacedDigitSystemFontOfSize:9.5 + weight:NSFontWeightRegular], + NSFontAttributeName, + fgMenuThemeColor, NSForegroundColorAttributeName, + nil]]; // Using NSParagraphStyle to right align clipped weird, so do it manually // Also draw low to ignore descenders NSSize renderSize = [renderString size]; [renderString drawAtPoint:NSMakePoint(menuWidth - kMemPagingDisplayWidth + - roundf((kMemPagingDisplayWidth - (float)renderSize.width) / 2.0f), - 4.0f)]; // Just hardcode the vertical offset - - // Unlock focus - [image unlockFocus]; - + round((kMemPagingDisplayWidth - renderSize.width) / 2.0), + 4.0)]; // Just hardcode the vertical offset } // renderPageIndicator /////////////////////////////////////////////////////////////// // -// Timer callbacks +// Timer callbacks // /////////////////////////////////////////////////////////////// - (void)timerFired:(NSTimer *)timer { NSDictionary *currentStats = [memStats memStats]; - if (!currentStats) return; + if (!currentStats) + return; // Add to history (at least one) if ([ourPrefs memDisplayMode] == kMemDisplayGraph) { if ([memHistory count] >= [ourPrefs memGraphLength]) { [memHistory removeObjectsInRange:NSMakeRange(0, [memHistory count] - [ourPrefs memGraphLength] + 1)]; } - } else { + } + else { [memHistory removeAllObjects]; } [memHistory addObject:currentStats]; @@ -865,73 +930,79 @@ - (void)updateMenuWhenDown { /////////////////////////////////////////////////////////////// // -// Prefs +// Prefs // /////////////////////////////////////////////////////////////// - (void)configFromPrefs:(NSNotification *)notification { #ifdef ELCAPITAN - [super configDisplay:kMemMenuBundleID fromPrefs:ourPrefs withTimerInterval:[ourPrefs memInterval]]; + [super configDisplay:kMemMenuBundleID + fromPrefs:ourPrefs + withTimerInterval:[ourPrefs memInterval]]; #endif - // Update prefs - [ourPrefs syncWithDisk]; - // Handle menubar theme changes - fgMenuThemeColor = self.menuBarTextColor; - + fgMenuThemeColor = self.menuBarTextColor; + // Cache colors to skip archive cycle from prefs - freeColor = [self colorByAdjustingForLightDark:[ourPrefs memFreeColor]]; - usedColor = [self colorByAdjustingForLightDark:[ourPrefs memUsedColor]]; - activeColor = [self colorByAdjustingForLightDark:[ourPrefs memActiveColor]]; - inactiveColor = [self colorByAdjustingForLightDark:[ourPrefs memInactiveColor]]; - wireColor = [self colorByAdjustingForLightDark:[ourPrefs memWireColor]]; - compressedColor = [self colorByAdjustingForLightDark:[ourPrefs memCompressedColor]]; - pageInColor = [self colorByAdjustingForLightDark:[ourPrefs memPageInColor]]; - pageOutColor = [self colorByAdjustingForLightDark:[ourPrefs memPageOutColor]]; + freeColor = [self colorByAdjustingForLightDark:[ourPrefs memFreeColor]]; + usedColor = [self colorByAdjustingForLightDark:[ourPrefs memUsedColor]]; + activeColor = [self colorByAdjustingForLightDark:[ourPrefs memActiveColor]]; + inactiveColor = [self colorByAdjustingForLightDark:[ourPrefs memInactiveColor]]; + wireColor = [self colorByAdjustingForLightDark:[ourPrefs memWireColor]]; + compressedColor = [self colorByAdjustingForLightDark:[ourPrefs memCompressedColor]]; + pageInColor = [self colorByAdjustingForLightDark:[ourPrefs memPageInColor]]; + pageOutColor = [self colorByAdjustingForLightDark:[ourPrefs memPageOutColor]]; // Since text rendering is so CPU intensive we minimize this by // prerendering what we can if we need it numberLabelPrerender = nil; NSAttributedString *renderUString = [[NSAttributedString alloc] - initWithString:[[NSBundle bundleForClass:[self class]] - localizedStringForKey:kUsedLabel - value:nil - table:nil] - attributes:[NSDictionary dictionaryWithObjectsAndKeys: - [NSFont monospacedDigitSystemFontOfSize:9.5f weight:NSFontWeightRegular], NSFontAttributeName, - usedColor, NSForegroundColorAttributeName, - nil]]; + initWithString:[[NSBundle bundleForClass:[self class]] + localizedStringForKey:kUsedLabel + value:nil + table:nil] + attributes:[NSDictionary dictionaryWithObjectsAndKeys: + [NSFont monospacedDigitSystemFontOfSize:9.5 + weight:NSFontWeightRegular], + NSFontAttributeName, + usedColor, NSForegroundColorAttributeName, + nil]]; NSAttributedString *renderFString = [[NSAttributedString alloc] - initWithString:[[NSBundle bundleForClass:[self class]] - localizedStringForKey:kFreeLabel - value:nil - table:nil] - attributes:[NSDictionary dictionaryWithObjectsAndKeys: - [NSFont monospacedDigitSystemFontOfSize:9.5f weight:NSFontWeightRegular], NSFontAttributeName, - freeColor, NSForegroundColorAttributeName, - nil]]; + initWithString:[[NSBundle bundleForClass:[self class]] + localizedStringForKey:kFreeLabel + value:nil + table:nil] + attributes:[NSDictionary dictionaryWithObjectsAndKeys: + [NSFont monospacedDigitSystemFontOfSize:9.5 + weight:NSFontWeightRegular], + NSFontAttributeName, + freeColor, NSForegroundColorAttributeName, + nil]]; if ([renderUString size].width > [renderFString size].width) { numberLabelPrerender = [[NSImage alloc] initWithSize:NSMakeSize([renderUString size].width, - self.height-1)]; - } else { + self.height - 1)]; + } + else { numberLabelPrerender = [[NSImage alloc] initWithSize:NSMakeSize([renderFString size].width, - self.height-1)]; + self.height - 1)]; } [numberLabelPrerender lockFocus]; // No descenders so render both lines lower than normal - [renderUString drawAtPoint:NSMakePoint(0, (float)floor([numberLabelPrerender size].height / 2) - 1)]; + [renderUString drawAtPoint:NSMakePoint(0, floor([numberLabelPrerender size].height / 2.0) - 1)]; [renderFString drawAtPoint:NSMakePoint(0, -1)]; [numberLabelPrerender unlockFocus]; // Figure out the length of "MB" localization float mbLength = 0; if ([ourPrefs memDisplayMode] == kMemDisplayNumber) { - NSAttributedString *renderMBString = [[NSAttributedString alloc] - initWithString:[localizedStrings objectForKey:kMBLabel] - attributes:[NSDictionary dictionaryWithObjectsAndKeys: - [NSFont monospacedDigitSystemFontOfSize:9.5f weight:NSFontWeightRegular], NSFontAttributeName, - nil]]; + NSAttributedString *renderMBString = [[NSAttributedString alloc] + initWithString:[localizedStrings objectForKey:kMBLabel] + attributes:[NSDictionary dictionaryWithObjectsAndKeys: + [NSFont monospacedDigitSystemFontOfSize:9.5 + weight:NSFontWeightRegular], + NSFontAttributeName, + nil]]; mbLength = (float)ceil([renderMBString size].width); } @@ -946,10 +1017,12 @@ - (void)configFromPrefs:(NSNotification *)notification { if ([[[memStats memStats] objectForKey:@"totalmb"] unsignedLongLongValue] >= 10000) { menuWidth = kMemNumberDisplayExtraLongWidth + mbLength; textWidth = kMemNumberDisplayExtraLongWidth + mbLength; - } else if ([[[memStats memStats] objectForKey:@"totalmb"] unsignedLongLongValue] >= 1000) { + } + else if ([[[memStats memStats] objectForKey:@"totalmb"] unsignedLongLongValue] >= 1000) { menuWidth = kMemNumberDisplayLongWidth + mbLength; textWidth = kMemNumberDisplayLongWidth + mbLength; - } else { + } + else { menuWidth = kMemNumberDisplayShortWidth + mbLength; textWidth = kMemNumberDisplayShortWidth + mbLength; } @@ -970,9 +1043,8 @@ - (void)configFromPrefs:(NSNotification *)notification { menuWidth += kMemPagingDisplayWidth + kMemPagingDisplayGapWidth; } - // Force initial update - statusItem.button.image=self.image; + statusItem.button.image = self.image; } // configFromPrefs @end diff --git a/MenuExtras/MenuMeterMem/MenuMeterMemStats.h b/MenuExtras/MenuMeterMem/MenuMeterMemStats.h index 627d5ee0..b14e3314 100644 --- a/MenuExtras/MenuMeterMem/MenuMeterMemStats.h +++ b/MenuExtras/MenuMeterMem/MenuMeterMemStats.h @@ -1,59 +1,60 @@ // // MenuMeterMemStats.h // -// Reader object for VM info +// Reader object for VM info // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -#import +#import "MenuMeterWorkarounds.h" #import +#import #import #import #import #import #import -#import "MenuMeterWorkarounds.h" - @interface MenuMeterMemStats : NSObject { // Mach host - mach_port_t selfHost; + mach_port_t selfHost; // Total RAM - uint64_t totalRAM; + uint64_t totalRAM; // Tiger or later? - BOOL isTigerOrLater; + BOOL isTigerOrLater; // Mavericks or later? - BOOL isMavericksOrLater; + BOOL isMavericksOrLater; // Path to swap - NSString *swapPath; + NSString *swapPath; // Swap name prefix - NSString *swapPrefix; + NSString *swapPrefix; // Max swap count - uint32_t peakSwapFiles; + uint32_t peakSwapFiles; // Last paging counts - uint64_t lastPageIn, lastPageOut; + uint64_t lastPageIn, lastPageOut; } // MenuMeterMemStats // Mem usage info + - (NSDictionary *)memStats; + - (NSDictionary *)swapStats; @end diff --git a/MenuExtras/MenuMeterMem/MenuMeterMemStats.m b/MenuExtras/MenuMeterMem/MenuMeterMemStats.m index 472ff0a4..ed8876c8 100644 --- a/MenuExtras/MenuMeterMem/MenuMeterMemStats.m +++ b/MenuExtras/MenuMeterMem/MenuMeterMemStats.m @@ -1,64 +1,64 @@ // // MenuMeterMemStats.m // -// Reader object for VM info +// Reader object for VM info // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #import "MenuMeterMemStats.h" -#include #include +#include /////////////////////////////////////////////////////////////// // -// Definitions for 64-bit from 10.9+ so we can still use old SDKs. +// Definitions for 64-bit from 10.9+ so we can still use old SDKs. // /////////////////////////////////////////////////////////////// #ifndef ELCAPITAN struct vm_statistics64 { - natural_t free_count; - natural_t active_count; - natural_t inactive_count; - natural_t wire_count; - uint64_t zero_fill_count; - uint64_t reactivations; - uint64_t pageins; - uint64_t pageouts; - uint64_t faults; - uint64_t cow_faults; - uint64_t lookups; - uint64_t hits; - uint64_t purges; - natural_t purgeable_count; - natural_t speculative_count; - uint64_t decompressions; - uint64_t compressions; - uint64_t swapins; - uint64_t swapouts; - natural_t compressor_page_count; - natural_t throttled_count; - natural_t external_page_count; - natural_t internal_page_count; - uint64_t total_uncompressed_pages_in_compressor; + natural_t free_count; + natural_t active_count; + natural_t inactive_count; + natural_t wire_count; + uint64_t zero_fill_count; + uint64_t reactivations; + uint64_t pageins; + uint64_t pageouts; + uint64_t faults; + uint64_t cow_faults; + uint64_t lookups; + uint64_t hits; + uint64_t purges; + natural_t purgeable_count; + natural_t speculative_count; + uint64_t decompressions; + uint64_t compressions; + uint64_t swapins; + uint64_t swapouts; + natural_t compressor_page_count; + natural_t throttled_count; + natural_t external_page_count; + natural_t internal_page_count; + uint64_t total_uncompressed_pages_in_compressor; } __attribute__((aligned(8))); -typedef struct vm_statistics64 vm_statistics64_data_t; -typedef integer_t *host_info64_t; +typedef struct vm_statistics64 vm_statistics64_data_t; +typedef integer_t *host_info64_t; #endif typedef kern_return_t (*host_statistics64_Ptr)(host_t host_priv, host_flavor_t flavor, @@ -69,15 +69,16 @@ typedef kern_return_t (*host_statistics64_Ptr)(host_t host_priv, /////////////////////////////////////////////////////////////// // -// Private methods and constants +// Private methods and constants // /////////////////////////////////////////////////////////////// // Default strings for swap file login -#define kDefaultSwapPath @"/private/var/vm/" -#define kDefaultSwapPrefix @"swapfile" +#define kDefaultSwapPath @"/private/var/vm/" +#define kDefaultSwapPrefix @"swapfile" @interface MenuMeterMemStats (PrivateMethods) + - (void)initializeSwapPath; @end @@ -85,7 +86,7 @@ @implementation MenuMeterMemStats /////////////////////////////////////////////////////////////// // -// Load +// Load // /////////////////////////////////////////////////////////////// @@ -95,11 +96,11 @@ + (void)load { /////////////////////////////////////////////////////////////// // -// init/dealloc +// init/dealloc // /////////////////////////////////////////////////////////////// -- (id)init { +- (instancetype)init { self = [super init]; if (!self) { return nil; @@ -128,12 +129,11 @@ - (id)init { } // init - // dealloc - +// dealloc /////////////////////////////////////////////////////////////// // -// Mem usage info +// Mem usage info // /////////////////////////////////////////////////////////////// @@ -153,7 +153,8 @@ - (NSDictionary *)memStats32 { uint64_t deltaPageIn = 0, deltaPageOut = 0; if ((natural_t)vmStats32.pageins >= lastPageIn) { deltaPageIn = (natural_t)vmStats32.pageins - lastPageIn; - } else { + } + else { #ifdef __LP64__ // 64-bit rollover? Nothing sane we can do deltaPageIn = (natural_t)vmStats32.pageins; @@ -163,7 +164,8 @@ - (NSDictionary *)memStats32 { } if ((natural_t)vmStats32.pageouts >= lastPageOut) { deltaPageOut = (natural_t)vmStats32.pageouts - lastPageOut; - } else { + } + else { #ifdef __LP64__ // 64-bit rollover? Nothing sane we can do deltaPageOut = (natural_t)vmStats32.pageouts; @@ -218,7 +220,7 @@ - (NSDictionary *)memStats64 { vm_statistics64_data_t vmStats64; bzero(&vmStats64, sizeof(vm_statistics64_data_t)); // HOST_VM_INFO64_COUNT - mach_msg_type_number_t vmCount = (mach_msg_type_number_t)(sizeof(vm_statistics64_data_t)/sizeof(integer_t)); + mach_msg_type_number_t vmCount = (mach_msg_type_number_t)(sizeof(vm_statistics64_data_t) / sizeof(integer_t)); if (host_statistics64_Impl(selfHost, 4 /* HOST_VM_INFO64 */, (host_info64_t)&vmStats64, &vmCount) != KERN_SUCCESS) { return nil; } @@ -227,12 +229,14 @@ - (NSDictionary *)memStats64 { uint64_t deltaPageIn = 0, deltaPageOut = 0; if (vmStats64.pageins >= lastPageIn) { deltaPageIn = vmStats64.pageins - lastPageIn; - } else { + } + else { deltaPageIn = vmStats64.pageins; } if (vmStats64.pageouts >= lastPageOut) { deltaPageOut = vmStats64.pageouts - lastPageOut; - } else { + } + else { deltaPageOut = vmStats64.pageouts; } // Update history @@ -250,20 +254,20 @@ - (NSDictionary *)memStats64 { // Update total totalRAM = active + inactive + wired + free + compressed; - int memory_pressure_level; - size_t length = sizeof(int); - - sysctlbyname("kern.memorystatus_vm_pressure_level", &memory_pressure_level, &length, nil, 0); + int memory_pressure_level; + size_t length = sizeof(int); + + sysctlbyname("kern.memorystatus_vm_pressure_level", &memory_pressure_level, &length, nil, 0); + + int memory_pressure = [self memPressure]; - int memory_pressure=[self memPressure]; - return [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithDouble:(double)totalRAM / 1048576], @"totalmb", // See discussion in 32 bit code for historical difference between free/used. // By that standard compressed pages are probably active (OS compressing // rather than purging). [NSNumber numberWithDouble:(double)(free + inactive) / 1048576], @"freemb", - [NSNumber numberWithDouble:(double)(active + wired + compressed) / 1048576], @"usedmb", + [NSNumber numberWithDouble:(double)(active + wired + compressed) / 1048576], @"usedmb", [NSNumber numberWithDouble:(double)active / 1048576], @"activemb", [NSNumber numberWithDouble:(double)inactive / 1048576], @"inactivemb", [NSNumber numberWithDouble:(double)wired / 1048576], @"wiremb", @@ -284,15 +288,16 @@ - (NSDictionary *)memStats64 { [NSNumber numberWithUnsignedLongLong:vmStats64.compressions], @"compressions", [NSNumber numberWithUnsignedLongLong:deltaPageIn], @"deltapageins", [NSNumber numberWithUnsignedLongLong:deltaPageOut], @"deltapageouts", - [NSNumber numberWithInt:memory_pressure], @"mempress", - [NSNumber numberWithInt:memory_pressure_level], @"mempresslevel", + [NSNumber numberWithInt:memory_pressure], @"mempress", + [NSNumber numberWithInt:memory_pressure_level], @"mempresslevel", nil]; } // memStats64 - (NSDictionary *)memStats { if (isMavericksOrLater) { return [self memStats64]; - } else { + } + else { return [self memStats32]; } } // memStats @@ -303,7 +308,8 @@ - (NSDictionary *)swapStats { // but that occassionally crashed on load. So now we defer as much as possible if (!swapPath) { [self initializeSwapPath]; - if (!swapPath) return nil; + if (!swapPath) + return nil; } // Does the path exist? How many files? @@ -318,12 +324,13 @@ - (NSDictionary *)swapStats { while ((currentFile = [dirEnum nextObject])) { NSString *currentFileFullPath = [swapPath stringByAppendingPathComponent:currentFile]; if ([currentFile hasPrefix:swapPrefix] && - [fm fileExistsAtPath:currentFileFullPath isDirectory:&isDir] && - !isDir) { + [fm fileExistsAtPath:currentFileFullPath + isDirectory:&isDir] && + !isDir) { swapCount++; swapSize += [[[fm attributesOfItemAtPath:currentFileFullPath - error:nil] - objectForKey:NSFileSize] unsignedLongLongValue]; + error:nil] + objectForKey:NSFileSize] unsignedLongLongValue]; } } } @@ -337,7 +344,7 @@ - (NSDictionary *)swapStats { BOOL encrypted = NO; uint64_t swapUsed = 0; if (isTigerOrLater) { - int swapMIB[] = { CTL_VM, 5 }; + int swapMIB[] = {CTL_VM, 5}; struct xsw_usage swapUsage; size_t swapUsageSize = sizeof(swapUsage); memset(&swapUsage, 0, sizeof(swapUsage)); @@ -348,114 +355,114 @@ - (NSDictionary *)swapStats { } return [NSDictionary dictionaryWithObjectsAndKeys: - swapPath, @"swappath", - [NSNumber numberWithUnsignedInt:swapCount], @"swapcount", - [NSNumber numberWithUnsignedInt:peakSwapFiles], @"swapcountpeak", - [NSNumber numberWithUnsignedLongLong:swapSize / 1048576], @"swapsizemb", - [NSNumber numberWithUnsignedLongLong:swapUsed / 1048576], @"swapusedmb", - [NSNumber numberWithBool:encrypted], @"swapencrypted", - nil]; + swapPath, @"swappath", + [NSNumber numberWithUnsignedInt:swapCount], @"swapcount", + [NSNumber numberWithUnsignedInt:peakSwapFiles], @"swapcountpeak", + [NSNumber numberWithUnsignedLongLong:swapSize / 1048576], @"swapsizemb", + [NSNumber numberWithUnsignedLongLong:swapUsed / 1048576], @"swapusedmb", + [NSNumber numberWithBool:encrypted], @"swapencrypted", + nil]; } // swapStats /////////////////////////////////////////////////////////////// // -// Private methods +// Private methods // /////////////////////////////////////////////////////////////// - (void)initializeSwapPath { -/* this code seems to cause hangs for some users. - in any case, dynamic_pager is launched on demand from long time ago, and - you can't get the changed swap file path in this method, as far as I understand. - the rest is kept for historical interest. - this should fix https://github.com/yujitach/MenuMeters/issues/124 . - // We need to figure out where the swap file is. This information - // is not published by dynamic_pager to sysctl. We can't get dynamic_pager's - // arg list directed using sysctl because its UID 0. So we have to do some - // parsing of ps -axww output to get the info. - NSTask *psTask = [[NSTask alloc] init]; - [psTask setLaunchPath:@"/bin/ps"]; - [psTask setArguments:[NSArray arrayWithObjects:@"-axww", nil]]; - NSPipe *psPipe = [[NSPipe alloc] init]; - [psTask setStandardOutput:psPipe]; - NSFileHandle *psHandle = [psPipe fileHandleForReading]; - - // Do the launch in an exception block. Old style block for 10.2 compatibility. - // Accumulate all results into a single string for parse. - NSMutableString *psOutput = [@"" mutableCopy]; - NSMutableString *swapFullPath = [NSMutableString string]; - BOOL taskLaunched = NO; - NS_DURING - [psTask launch]; - while ([psTask isRunning]) { - [psOutput appendString:[[NSString alloc] initWithData:[psHandle availableData] - encoding:NSUTF8StringEncoding]]; - usleep(250000); - } - NS_HANDLER - // Catch - NSLog(@"MenuMeterMemStats unable to launch '/bin/ps'."); - taskLaunched = NO; - psOutput = nil; - NS_ENDHANDLER - if (psOutput) { - NSArray *psSplit = [psOutput componentsSeparatedByString:@"\n"]; - NSEnumerator *psLineWalk = [psSplit objectEnumerator]; - NSString *psLine = nil; - while ((psLine = [psLineWalk nextObject])) { - NSArray *psArgSplit = [psLine componentsSeparatedByString:@" "]; - if (([psArgSplit containsObject:@"dynamic_pager"] || [psArgSplit containsObject:@"/sbin/dynamic_pager"]) && - [psArgSplit containsObject:@"-F"]) { - // Consume all arguments till the next arg. This would fail - // on the path "/my/silly -swappath/" but is that really something - // we need to worry about? - for (CFIndex argIndex = [psArgSplit indexOfObject:@"-F"] + 1; argIndex < [psArgSplit count]; argIndex++) { - NSString *currentArg = [psArgSplit objectAtIndex:argIndex]; - if ([currentArg hasPrefix:@"-"]) break; - if ([swapFullPath length]) [swapFullPath appendString:@" "]; - [swapFullPath appendString:currentArg]; + /* this code seems to cause hangs for some users. + in any case, dynamic_pager is launched on demand from long time ago, and + you can't get the changed swap file path in this method, as far as I understand. + the rest is kept for historical interest. + this should fix https://github.com/yujitach/MenuMeters/issues/124 . + // We need to figure out where the swap file is. This information + // is not published by dynamic_pager to sysctl. We can't get dynamic_pager's + // arg list directed using sysctl because its UID 0. So we have to do some + // parsing of ps -axww output to get the info. + NSTask *psTask = [[NSTask alloc] init]; + [psTask setLaunchPath:@"/bin/ps"]; + [psTask setArguments:[NSArray arrayWithObjects:@"-axww", nil]]; + NSPipe *psPipe = [[NSPipe alloc] init]; + [psTask setStandardOutput:psPipe]; + NSFileHandle *psHandle = [psPipe fileHandleForReading]; + + // Do the launch in an exception block. Old style block for 10.2 compatibility. + // Accumulate all results into a single string for parse. + NSMutableString *psOutput = [@"" mutableCopy]; + NSMutableString *swapFullPath = [NSMutableString string]; + BOOL taskLaunched = NO; + NS_DURING + [psTask launch]; + while ([psTask isRunning]) { + [psOutput appendString:[[NSString alloc] initWithData:[psHandle availableData] + encoding:NSUTF8StringEncoding]]; + usleep(250000); + } + NS_HANDLER + // Catch + NSLog(@"MenuMeterMemStats unable to launch '/bin/ps'."); + taskLaunched = NO; + psOutput = nil; + NS_ENDHANDLER + if (psOutput) { + NSArray *psSplit = [psOutput componentsSeparatedByString:@"\n"]; + NSEnumerator *psLineWalk = [psSplit objectEnumerator]; + NSString *psLine = nil; + while ((psLine = [psLineWalk nextObject])) { + NSArray *psArgSplit = [psLine componentsSeparatedByString:@" "]; + if (([psArgSplit containsObject:@"dynamic_pager"] || [psArgSplit containsObject:@"/sbin/dynamic_pager"]) && + [psArgSplit containsObject:@"-F"]) { + // Consume all arguments till the next arg. This would fail + // on the path "/my/silly -swappath/" but is that really something + // we need to worry about? + for (CFIndex argIndex = [psArgSplit indexOfObject:@"-F"] + 1; argIndex < [psArgSplit count]; argIndex++) { + NSString *currentArg = [psArgSplit objectAtIndex:argIndex]; + if ([currentArg hasPrefix:@"-"]) break; + if ([swapFullPath length]) [swapFullPath appendString:@" "]; + [swapFullPath appendString:currentArg]; + } } + if (![swapFullPath isEqualToString:@""]) break; } - if (![swapFullPath isEqualToString:@""]) break; } - } - // Did we get it? - if (![swapFullPath isEqualToString:@""]) { - swapPath = [swapFullPath stringByDeletingLastPathComponent]; - swapPrefix = [swapFullPath lastPathComponent]; + // Did we get it? + if (![swapFullPath isEqualToString:@""]) { + swapPath = [swapFullPath stringByDeletingLastPathComponent]; + swapPrefix = [swapFullPath lastPathComponent]; + } + else { + NSLog(@"MenuMeterMemStats unable to locate dynamic_pager args. Assume default."); + */ + // and now we provide a modern code to get the info via sysctl. + // Apparently there are still people who changes the swap file path... see + // https://github.com/yujitach/MenuMeters/issues/164 + char swapfileprefix[1024]; + size_t size = sizeof(swapfileprefix); + if (!sysctlbyname("vm.swapfileprefix", swapfileprefix, &size, NULL, 0)) { + NSString *x = [NSString stringWithUTF8String:swapfileprefix]; + swapPrefix = [x lastPathComponent]; + swapPath = [[x stringByDeletingLastPathComponent] stringByAppendingString:@"/"]; } else { - NSLog(@"MenuMeterMemStats unable to locate dynamic_pager args. Assume default."); - */ - // and now we provide a modern code to get the info via sysctl. - // Apparently there are still people who changes the swap file path... see - // https://github.com/yujitach/MenuMeters/issues/164 - char swapfileprefix[1024]; - size_t size = sizeof(swapfileprefix); - if (!sysctlbyname("vm.swapfileprefix", swapfileprefix, &size, NULL, 0)){ - NSString*x=[NSString stringWithUTF8String:swapfileprefix]; - swapPrefix=[x lastPathComponent]; - swapPath=[[x stringByDeletingLastPathComponent] stringByAppendingString:@"/"]; - }else{ swapPath = kDefaultSwapPath; swapPrefix = kDefaultSwapPrefix; - } - + } } // initializeSwapPath -- (int)memPressure -{ - // taken from https://github.com/tramdas/memstatpoller/blob/38fbb15efc9b28db508d21ef557c89b4b29fd94e/main.c#L95 - int error; - int level=0; - // This is how AAPL's memory_pressure tool reports "System-wide memory free percentage": - //error = memorystatus_get_level((user_addr_t) level); - error = syscall(SYS_memorystatus_get_level, &level); - if(error){ - NSLog(@"memorystatus_get_level failed: error=%@ errorno=%@ (%s)",@(error),@(errno),strerror(errno)); - } - return level; +- (int)memPressure { + // taken from https://github.com/tramdas/memstatpoller/blob/38fbb15efc9b28db508d21ef557c89b4b29fd94e/main.c#L95 + int error; + int level = 0; + // This is how AAPL's memory_pressure tool reports "System-wide memory free percentage": + // error = memorystatus_get_level((user_addr_t) level); + error = syscall(SYS_memorystatus_get_level, &level); + if (error) { + NSLog(@"memorystatus_get_level failed: error=%@ errorno=%@ (%s)", @(error), @(errno), strerror(errno)); + } + return level; } + @end diff --git a/MenuExtras/MenuMeterNet/MenuMeterNetConfig.h b/MenuExtras/MenuMeterNet/MenuMeterNetConfig.h index 4e7a359f..e230a743 100644 --- a/MenuExtras/MenuMeterNet/MenuMeterNetConfig.h +++ b/MenuExtras/MenuMeterNet/MenuMeterNetConfig.h @@ -1,68 +1,77 @@ // // MenuMeterNetConfig.h // -// Reader object for network config info +// Reader object for network config info // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // +#import "MenuMeterNet.h" +#import "MenuMeterNetPPP.h" #import -#import #import +#import #import #import -#import +#import #import -#import "MenuMeterNet.h" -#import "MenuMeterNetPPP.h" - @interface MenuMeterNetConfig : NSObject { // PPP data pull - MenuMeterNetPPP *pppGatherer; + MenuMeterNetPPP *pppGatherer; // Values for SystemConfiguration sessions - SCDynamicStoreRef scSession; - CFRunLoopSourceRef scRunSource; + SCDynamicStoreRef scSession; + CFRunLoopSourceRef scRunSource; // Mach port for IOKit - mach_port_t masterPort; + mach_port_t masterPort; // Caches of current data - NSArray *cachedInterfaceDetails; - NSString *cachedPrimaryName; - NSString *cachedPrimaryService; - NSMutableDictionary *cachedServiceToName; - NSMutableDictionary *cachedNameToService; - NSMutableDictionary *cachedServiceSpeed; - NSMutableDictionary *cachedUnderlyingInterface; - NSMutableDictionary *cachedInterfaceUp; + NSArray *cachedInterfaceDetails; + NSString *cachedPrimaryName; + NSString *cachedPrimaryService; + NSMutableDictionary *cachedServiceToName; + NSMutableDictionary *cachedNameToService; + NSMutableDictionary *cachedServiceSpeed; + NSMutableDictionary *cachedUnderlyingInterface; + NSMutableDictionary *cachedInterfaceUp; } // MenuMeterNetConfig // Network config info + - (NSString *)computerName; + - (NSDictionary *)interfaceConfigForInterfaceName:(NSString *)name; + - (NSArray *)interfaceDetails; + - (NSString *)primaryInterfaceName; + - (NSString *)primaryServiceID; + - (NSString *)serviceForInterfaceName:(NSString *)interfaceName; + - (NSString *)interfaceNameForServiceID:(NSString *)serviceID; + - (NSNumber *)speedForServiceID:(NSString *)serviceID; + - (NSString *)underlyingInterfaceNameForServiceID:(NSString *)serviceID; + - (BOOL)interfaceNameIsUp:(NSString *)interfaceName; @end diff --git a/MenuExtras/MenuMeterNet/MenuMeterNetConfig.m b/MenuExtras/MenuMeterNet/MenuMeterNetConfig.m index f650709e..4776e1d2 100644 --- a/MenuExtras/MenuMeterNet/MenuMeterNetConfig.m +++ b/MenuExtras/MenuMeterNet/MenuMeterNetConfig.m @@ -1,66 +1,69 @@ // // MenuMeterNetConfig.m // -// Reader object for network config info +// Reader object for network config info // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #import "MenuMeterNetConfig.h" - /////////////////////////////////////////////////////////////// // -// Private methods and constants +// Private methods and constants // /////////////////////////////////////////////////////////////// // Speed defines -#define kInterfaceDefaultSpeed -1 -#define kModemInterfaceDefaultSpeed 56000 +#define kInterfaceDefaultSpeed -1 +#define kModemInterfaceDefaultSpeed 56000 @interface MenuMeterNetConfig (PrivateMethods) + - (void)clearCaches; + - (NSDictionary *)sysconfigValueForKey:(NSString *)key; + - (NSNumber *)speedForInterfaceName:(NSString *)bsdInterface; @end /////////////////////////////////////////////////////////////// // -// SystemConfiguration notification callbacks +// SystemConfiguration notification callbacks // /////////////////////////////////////////////////////////////// static void scChangeCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) { - if (info) [(__bridge MenuMeterNetConfig *)info clearCaches]; + if (info) + [(__bridge MenuMeterNetConfig *)info clearCaches]; } // scChangeCallback /////////////////////////////////////////////////////////////// // -// init/dealloc +// init/dealloc // /////////////////////////////////////////////////////////////// @implementation MenuMeterNetConfig -- (id)init { +- (instancetype)init { self = [super init]; if (!self) { @@ -77,7 +80,7 @@ - (id)init { // Connect to SystemConfiguration SCDynamicStoreContext scContext; scContext.version = 0; - scContext.info = (__bridge void * _Nullable)(self); + scContext.info = (__bridge void *_Nullable)(self); scContext.retain = NULL; scContext.release = NULL; scContext.copyDescription = NULL; @@ -91,11 +94,11 @@ - (id)init { } if (!SCDynamicStoreSetNotificationKeys(scSession, (CFArrayRef)[NSArray arrayWithObjects: - @"State:/Network/Global/IPv4", - @"Setup:/Network/Global/IPv4", - @"State:/Network/Interface", nil], + @"State:/Network/Global/IPv4", + @"Setup:/Network/Global/IPv4", + @"State:/Network/Interface", nil], (CFArrayRef)[NSArray arrayWithObjects: - @"State:/Network/Interface.*", nil])) { + @"State:/Network/Interface.*", nil])) { NSLog(@"MenuMeterNetConfig unable to install notification keys."); return nil; } @@ -134,14 +137,14 @@ - (void)dealloc { /////////////////////////////////////////////////////////////// // -// Network config info +// Network config info // /////////////////////////////////////////////////////////////// - (NSString *)computerName { CFStringRef name = SCDynamicStoreCopyComputerName(scSession, NULL); - return (NSString *)CFBridgingRelease(name); + return (NSString *)CFBridgingRelease(name); } // computerName @@ -159,18 +162,19 @@ - (NSDictionary *)interfaceConfigForInterfaceName:(NSString *)name { NSString *primaryName = [self primaryInterfaceName]; if (service && (statName || primaryName)) { return [NSDictionary dictionaryWithObjectsAndKeys: - service, - @"service", - (statName ? statName : primaryName), - @"statname", - [self speedForServiceID:service], - @"speed", - kNetPrimaryInterface, - @"name", - [NSNumber numberWithBool:[self interfaceNameIsUp:(statName ? statName : primaryName)]], - @"interfaceup", - nil]; - } else { + service, + @"service", + (statName ? statName : primaryName), + @"statname", + [self speedForServiceID:service], + @"speed", + kNetPrimaryInterface, + @"name", + [NSNumber numberWithBool:[self interfaceNameIsUp:(statName ? statName : primaryName)]], + @"interfaceup", + nil]; + } + else { return nil; } } @@ -179,17 +183,17 @@ - (NSDictionary *)interfaceConfigForInterfaceName:(NSString *)name { NSString *statName = [self underlyingInterfaceNameForServiceID:service]; if (service && statName) { return [NSDictionary dictionaryWithObjectsAndKeys: - service, - @"service", - statName, - @"statname", - [self speedForServiceID:service], - @"speed", - name, - @"name", - [NSNumber numberWithBool:[self interfaceNameIsUp:statName]], - @"interfaceup", - nil]; + service, + @"service", + statName, + @"statname", + [self speedForServiceID:service], + @"speed", + name, + @"name", + [NSNumber numberWithBool:[self interfaceNameIsUp:statName]], + @"interfaceup", + nil]; } return nil; @@ -216,11 +220,13 @@ - (NSArray *)interfaceDetails { // Get the dict block for services NSDictionary *servicesDict = [self sysconfigValueForKey:@"Setup:/Network/Global/IPv4"]; - if (!servicesDict) return nil; + if (!servicesDict) + return nil; // Get the array of services NSMutableArray *allServices = [[servicesDict objectForKey:@"ServiceOrder"] mutableCopy]; - if (!allServices) return nil; + if (!allServices) + return nil; // Reorder services so the primary is first if possible if ([self primaryServiceID]) { @@ -242,18 +248,19 @@ - (NSArray *)interfaceDetails { // Is this the primary? if ([[self primaryServiceID] isEqualToString:serviceID]) { [interfaceDetail setObject:[NSNumber numberWithBool:YES] forKey:@"primary"]; - } else { + } + else { [interfaceDetail setObject:[NSNumber numberWithBool:NO] forKey:@"primary"]; } // Get the interface name NSDictionary *serviceDict = [self sysconfigValueForKey: - [NSString stringWithFormat:@"Setup:/Network/Service/%@", serviceID]]; + [NSString stringWithFormat:@"Setup:/Network/Service/%@", serviceID]]; if ([serviceDict objectForKey:@"UserDefinedName"]) { [interfaceDetail setObject:[serviceDict objectForKey:@"UserDefinedName"] forKey:@"name"]; } // Get interface details NSDictionary *interfaceDict = [self sysconfigValueForKey: - [NSString stringWithFormat:@"Setup:/Network/Service/%@/Interface", serviceID]]; + [NSString stringWithFormat:@"Setup:/Network/Service/%@/Interface", serviceID]]; if (!interfaceDict) { // If the details aren't present then skip, we can learn nothing here continue; @@ -262,9 +269,11 @@ - (NSArray *)interfaceDetails { if (![interfaceDetail objectForKey:@"name"]) { if ([interfaceDict objectForKey:@"UserDefinedName"]) { [interfaceDetail setObject:[interfaceDict objectForKey:@"UserDefinedName"] forKey:@"name"]; - } else if ([interfaceDict objectForKey:@"Hardware"]) { + } + else if ([interfaceDict objectForKey:@"Hardware"]) { [interfaceDetail setObject:[interfaceDict objectForKey:@"Hardware"] forKey:@"name"]; - } else { + } + else { [interfaceDetail setObject:@"Unknown Interface" forKey:@"name"]; } } @@ -275,53 +284,54 @@ - (NSArray *)interfaceDetails { // Connection type if ([interfaceDict objectForKey:@"SubType"]) { [interfaceDetail setObject:[interfaceDict objectForKey:@"SubType"] forKey:@"connectiontype"]; - } else if ([interfaceDict objectForKey:@"Type"]) { + } + else if ([interfaceDict objectForKey:@"Type"]) { [interfaceDetail setObject:[interfaceDict objectForKey:@"Type"] forKey:@"connectiontype"]; } // Now get info that may or may not be there, starting with PPP name NSDictionary *pppDict = [self sysconfigValueForKey: - [NSString stringWithFormat:@"State:/Network/Service/%@/PPP", serviceID]]; + [NSString stringWithFormat:@"State:/Network/Service/%@/PPP", serviceID]]; if ([pppDict objectForKey:@"InterfaceName"]) { [interfaceDetail setObject:[pppDict objectForKey:@"InterfaceName"] forKey:@"devicepppname"]; } pppDict = [self sysconfigValueForKey:[NSString stringWithFormat:@"Setup:/Network/Service/%@/PPP", serviceID]]; if (pppDict) { // It's PPP, get the status info - NSDictionary *pppStatusDict= [pppGatherer statusForServiceID:serviceID]; + NSDictionary *pppStatusDict = [pppGatherer statusForServiceID:serviceID]; if (pppStatusDict) { [interfaceDetail setObject:pppStatusDict forKey:@"pppstatus"]; } } // IPv4 info NSDictionary *ipDict = [self sysconfigValueForKey: - [NSString stringWithFormat:@"State:/Network/Service/%@/IPv4", serviceID]]; + [NSString stringWithFormat:@"State:/Network/Service/%@/IPv4", serviceID]]; if ([ipDict objectForKey:@"Addresses"]) { [interfaceDetail setObject:[ipDict objectForKey:@"Addresses"] forKey:@"ipv4addresses"]; } // IPv6 info if ([interfaceDetail objectForKey:@"devicename"]) { ipDict = [self sysconfigValueForKey: - [NSString stringWithFormat:@"State:/Network/Interface/%@/IPv6", - [interfaceDetail objectForKey:@"devicename"]]]; + [NSString stringWithFormat:@"State:/Network/Interface/%@/IPv6", + [interfaceDetail objectForKey:@"devicename"]]]; if ([ipDict objectForKey:@"Addresses"]) { [interfaceDetail setObject:[ipDict objectForKey:@"Addresses"] forKey:@"ipv6addresses"]; } } // Appletalk NSDictionary *appletalkDict = [self sysconfigValueForKey: - [NSString stringWithFormat:@"State:/Network/Interface/%@/AppleTalk", - [interfaceDetail objectForKey:@"devicename"]]]; + [NSString stringWithFormat:@"State:/Network/Interface/%@/AppleTalk", + [interfaceDetail objectForKey:@"devicename"]]]; if ([appletalkDict objectForKey:@"NetworkID"] && - [appletalkDict objectForKey:@"NodeID"] && - [appletalkDict objectForKey:@"DefaultZone"]) { + [appletalkDict objectForKey:@"NodeID"] && + [appletalkDict objectForKey:@"DefaultZone"]) { [interfaceDetail setObject:[appletalkDict objectForKey:@"NetworkID"] forKey:@"appletalknetid"]; [interfaceDetail setObject:[appletalkDict objectForKey:@"NodeID"] forKey:@"appletalknodeid"]; [interfaceDetail setObject:[appletalkDict objectForKey:@"DefaultZone"] forKey:@"appletalkzone"]; } // Link status NSDictionary *linkDict = [self sysconfigValueForKey: - [NSString stringWithFormat:@"State:/Network/Interface/%@/Link", - [interfaceDetail objectForKey:@"devicename"]]]; + [NSString stringWithFormat:@"State:/Network/Interface/%@/Link", + [interfaceDetail objectForKey:@"devicename"]]]; if ([linkDict objectForKey:@"Active"]) { [interfaceDetail setObject:[linkDict objectForKey:@"Active"] forKey:@"linkactive"]; } @@ -332,17 +342,18 @@ - (NSArray *)interfaceDetails { if ([[interfaceDetail objectForKey:@"devicename"] hasPrefix:@"en"]) { // Ethernet interface so we can ask IOKit [interfaceDetail setObject:[self speedForInterfaceName:[interfaceDetail objectForKey:@"devicename"]] forKey:@"linkspeed"]; - } else if ([[interfaceDetail objectForKey:@"devicename"] isEqualToString:@"modem"]) { + } + else if ([[interfaceDetail objectForKey:@"devicename"] isEqualToString:@"modem"]) { // Modem data can be had from config framework NSDictionary *modemDict = [self sysconfigValueForKey: - [NSString stringWithFormat:@"State:/Network/Service/%@/Modem", serviceID]]; + [NSString stringWithFormat:@"State:/Network/Service/%@/Modem", serviceID]]; if ([modemDict objectForKey:@"ConnectSpeed"]) { // Its a modem, but is it connected? pppDict = [self sysconfigValueForKey: - [NSString stringWithFormat:@"State:/Network/Service/%@/PPP", serviceID]]; + [NSString stringWithFormat:@"State:/Network/Service/%@/PPP", serviceID]]; if ([pppDict objectForKey:@"Status"] && - ([[pppDict objectForKey:@"Status"] intValue] == PPP_RUNNING) && - [pppDict objectForKey:@"ConnectSpeed"]) { + ([[pppDict objectForKey:@"Status"] intValue] == PPP_RUNNING) && + [pppDict objectForKey:@"ConnectSpeed"]) { [interfaceDetail setObject:[pppDict objectForKey:@"ConnectSpeed"] forKey:@"linkspeed"]; } } @@ -363,13 +374,15 @@ - (NSArray *)interfaceDetails { - (NSString *)primaryInterfaceName { // Cache? - if (cachedPrimaryName) return cachedPrimaryName; + if (cachedPrimaryName) + return cachedPrimaryName; // Get the primary service number NSDictionary *ipDict = [self sysconfigValueForKey:@"State:/Network/Global/IPv4"]; if ([ipDict objectForKey:@"PrimaryInterface"]) { cachedPrimaryName = [ipDict objectForKey:@"PrimaryInterface"]; - } else { + } + else { cachedPrimaryName = nil; } return cachedPrimaryName; @@ -379,13 +392,15 @@ - (NSString *)primaryInterfaceName { - (NSString *)primaryServiceID { // Cache? - if (cachedPrimaryService) return cachedPrimaryService; + if (cachedPrimaryService) + return cachedPrimaryService; // Get the primary service number NSDictionary *ipDict = [self sysconfigValueForKey:@"State:/Network/Global/IPv4"]; if ([ipDict objectForKey:@"PrimaryService"]) { cachedPrimaryService = [ipDict objectForKey:@"PrimaryService"]; - } else { + } + else { cachedPrimaryService = nil; } return cachedPrimaryService; @@ -394,20 +409,22 @@ - (NSString *)primaryServiceID { - (NSString *)interfaceNameForServiceID:(NSString *)serviceID { - if (!serviceID) return nil; + if (!serviceID) + return nil; // Cache? if ([cachedServiceToName objectForKey:serviceID]) { return [cachedServiceToName objectForKey:serviceID]; - } else if (!cachedServiceToName) { + } + else if (!cachedServiceToName) { cachedServiceToName = [NSMutableDictionary dictionary]; } // Get interface details NSDictionary *interfaceDict = [self sysconfigValueForKey: - [NSString stringWithFormat:@"Setup:/Network/Service/%@/Interface", serviceID]]; + [NSString stringWithFormat:@"Setup:/Network/Service/%@/Interface", serviceID]]; NSDictionary *pppDict = [self sysconfigValueForKey: - [NSString stringWithFormat:@"State:/Network/Service/%@/PPP", serviceID]]; + [NSString stringWithFormat:@"State:/Network/Service/%@/PPP", serviceID]]; // Check for PPP first if ([pppDict objectForKey:@"InterfaceName"]) { [cachedServiceToName setObject:[pppDict objectForKey:@"InterfaceName"] forKey:serviceID]; @@ -424,20 +441,24 @@ - (NSString *)interfaceNameForServiceID:(NSString *)serviceID { - (NSString *)serviceForInterfaceName:(NSString *)interfaceName { - if (!interfaceName) return nil; + if (!interfaceName) + return nil; if ([cachedNameToService objectForKey:interfaceName]) { return [cachedNameToService objectForKey:interfaceName]; - } else if (!cachedNameToService) { + } + else if (!cachedNameToService) { cachedNameToService = [NSMutableDictionary dictionary]; } // Get the dict block for services NSDictionary *ipDict = [self sysconfigValueForKey:@"Setup:/Network/Global/IPv4"]; - if (!ipDict) return nil; + if (!ipDict) + return nil; // Get the array of services NSMutableArray *allServices = [[ipDict objectForKey:@"ServiceOrder"] mutableCopy]; - if (!allServices) return nil; + if (!allServices) + return nil; // Set up the enumerator and loop the services NSEnumerator *servicesEnum = [allServices objectEnumerator]; @@ -445,13 +466,13 @@ - (NSString *)serviceForInterfaceName:(NSString *)interfaceName { while ((serviceID = [servicesEnum nextObject])) { // Get interface details NSDictionary *interfaceDict = [self sysconfigValueForKey: - [NSString stringWithFormat:@"Setup:/Network/Service/%@/Interface", serviceID]]; + [NSString stringWithFormat:@"Setup:/Network/Service/%@/Interface", serviceID]]; if ([[interfaceDict objectForKey:@"DeviceName"] isEqualToString:interfaceName]) { [cachedNameToService setObject:serviceID forKey:interfaceName]; return serviceID; } NSDictionary *pppDict = [self sysconfigValueForKey: - [NSString stringWithFormat:@"State:/Network/Service/%@/PPP", serviceID]]; + [NSString stringWithFormat:@"State:/Network/Service/%@/PPP", serviceID]]; if ([[pppDict objectForKey:@"InterfaceName"] isEqualToString:interfaceName]) { [cachedNameToService setObject:serviceID forKey:interfaceName]; return serviceID; @@ -463,12 +484,14 @@ - (NSString *)serviceForInterfaceName:(NSString *)interfaceName { - (NSNumber *)speedForServiceID:(NSString *)serviceID { - if (!serviceID) return [NSNumber numberWithLong:kInterfaceDefaultSpeed]; + if (!serviceID) + return [NSNumber numberWithLong:kInterfaceDefaultSpeed]; // Cache? if ([cachedServiceSpeed objectForKey:serviceID]) { return [cachedServiceSpeed objectForKey:serviceID]; - } else if (!cachedServiceSpeed) { + } + else if (!cachedServiceSpeed) { cachedServiceSpeed = [NSMutableDictionary dictionary]; } @@ -482,7 +505,8 @@ - (NSNumber *)speedForServiceID:(NSString *)serviceID { if ([modemDict objectForKey:@"ConnectSpeed"] && ([[pppDict objectForKey:@"Status"] intValue] == PPP_RUNNING)) { [cachedServiceSpeed setObject:[modemDict objectForKey:@"ConnectSpeed"] forKey:serviceID]; return [modemDict objectForKey:@"ConnectSpeed"]; - } else { + } + else { // Not connected or bad data, so use the modem default but don't cache return [NSNumber numberWithLong:kModemInterfaceDefaultSpeed]; } @@ -505,23 +529,24 @@ - (NSNumber *)speedForServiceID:(NSString *)serviceID { - (NSString *)underlyingInterfaceNameForServiceID:(NSString *)serviceID { - if (!serviceID) return nil; + if (!serviceID) + return nil; // Cache? if ([cachedUnderlyingInterface objectForKey:serviceID]) { return [cachedUnderlyingInterface objectForKey:serviceID]; - } else if (!cachedUnderlyingInterface) { + } + else if (!cachedUnderlyingInterface) { cachedUnderlyingInterface = [NSMutableDictionary dictionary]; } - // There appears to be a bug in pppconfd's handling of bytes sent for // PPPoE connections. Try to work around by finding the underlying ethernet // interface for these connections. NSDictionary *interfaceDict = [self sysconfigValueForKey: - [NSString stringWithFormat:@"Setup:/Network/Service/%@/Interface", serviceID]]; + [NSString stringWithFormat:@"Setup:/Network/Service/%@/Interface", serviceID]]; NSDictionary *pppDict = [self sysconfigValueForKey: - [NSString stringWithFormat:@"State:/Network/Service/%@/PPP", serviceID]]; + [NSString stringWithFormat:@"State:/Network/Service/%@/PPP", serviceID]]; // Check for PPP name if ([pppDict objectForKey:@"InterfaceName"]) { // There appears to be a bug in pppconfd's handling of bytes sent for @@ -530,7 +555,8 @@ - (NSString *)underlyingInterfaceNameForServiceID:(NSString *)serviceID { if ([[interfaceDict objectForKey:@"DeviceName"] hasPrefix:@"en"]) { [cachedUnderlyingInterface setObject:[interfaceDict objectForKey:@"DeviceName"] forKey:serviceID]; return [interfaceDict objectForKey:@"DeviceName"]; - } else { + } + else { [cachedUnderlyingInterface setObject:[pppDict objectForKey:@"InterfaceName"] forKey:serviceID]; return [pppDict objectForKey:@"InterfaceName"]; } @@ -546,32 +572,37 @@ - (NSString *)underlyingInterfaceNameForServiceID:(NSString *)serviceID { } // underlyingInterfaceNameForServiceID // Based on patch contributed by Da Woon Jung + - (BOOL)interfaceNameIsUp:(NSString *)interfaceName { - if (!interfaceName) return NO; + if (!interfaceName) + return NO; // Cache? if ([cachedInterfaceUp objectForKey:interfaceName]) { return [[cachedInterfaceUp objectForKey:interfaceName] boolValue]; - } else if (!cachedInterfaceUp) { + } + else if (!cachedInterfaceUp) { cachedInterfaceUp = [NSMutableDictionary dictionary]; } if ([interfaceName hasPrefix:@"en"]) { // Ethernet NSDictionary *linkDict = [self sysconfigValueForKey: - [NSString stringWithFormat:@"State:/Network/Interface/%@/Link", interfaceName]]; + [NSString stringWithFormat:@"State:/Network/Interface/%@/Link", interfaceName]]; if ([linkDict objectForKey:@"Active"]) { [cachedInterfaceUp setObject:[linkDict objectForKey:@"Active"] forKey:interfaceName]; return [[linkDict objectForKey:@"Active"] boolValue]; } - } else if ([interfaceName hasPrefix:@"ppp"]) { + } + else if ([interfaceName hasPrefix:@"ppp"]) { // PPP NSDictionary *pppDict = [pppGatherer statusForInterfaceName:interfaceName]; if ([[pppDict objectForKey:@"status"] intValue] == PPP_RUNNING) { [cachedInterfaceUp setObject:[NSNumber numberWithBool:YES] forKey:interfaceName]; return YES; - } else { + } + else { [cachedInterfaceUp setObject:[NSNumber numberWithBool:NO] forKey:interfaceName]; return NO; } @@ -584,110 +615,117 @@ - (BOOL)interfaceNameIsUp:(NSString *)interfaceName { /////////////////////////////////////////////////////////////// // -// Private methods +// Private methods // /////////////////////////////////////////////////////////////// // taken from https://stackoverflow.com/a/12310154/239243 -- (NSString *)runCommand:(NSString *)commandToRun -{ - NSTask *task = [[NSTask alloc] init]; - [task setLaunchPath:@"/bin/sh"]; - - NSArray *arguments = [NSArray arrayWithObjects: - @"-c" , - [NSString stringWithFormat:@"%@", commandToRun], - nil]; -// NSLog(@"run command:%@", commandToRun); - [task setArguments:arguments]; - - NSPipe *pipe = [NSPipe pipe]; - [task setStandardOutput:pipe]; - [task setStandardError:pipe]; - - NSFileHandle *file = [pipe fileHandleForReading]; - - [task launch]; - - NSData *data = [file readDataToEndOfFile]; - [file closeFile]; - - NSString *output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - return output; + +- (NSString *)runCommand:(NSString *)commandToRun { + NSTask *task = [[NSTask alloc] init]; + [task setLaunchPath:@"/bin/sh"]; + + NSArray *arguments = [NSArray arrayWithObjects: + @"-c", + [NSString stringWithFormat:@"%@", commandToRun], + nil]; + // NSLog(@"run command:%@", commandToRun); + [task setArguments:arguments]; + + NSPipe *pipe = [NSPipe pipe]; + [task setStandardOutput:pipe]; + [task setStandardError:pipe]; + + NSFileHandle *file = [pipe fileHandleForReading]; + + [task launch]; + + NSData *data = [file readDataToEndOfFile]; + [file closeFile]; + + NSString *output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + return output; } -- (NSNumber *)speedForInterfaceName:(NSString*)bsdInterface{ - { - NSDictionary* airportDict=[self sysconfigValueForKey:[NSString stringWithFormat:@"Setup:/Network/Interface/%@/AirPort",bsdInterface]]; - if(airportDict){ - NSNumber* x = [self speedForAirport]; - if(x){ - return x; - } - } - } - { - NSNumber* x=[self speedForInterfaceNameViaIOKit:bsdInterface]; - if(x){ - return x; - } - } - { - NSNumber* x=[self speedForInterfaceNameViaIfConfig:bsdInterface]; - if(x){ - return x; - } - } - return [NSNumber numberWithLong:kInterfaceDefaultSpeed]; +- (NSNumber *)speedForInterfaceName:(NSString *)bsdInterface { + { + NSDictionary *airportDict = [self sysconfigValueForKey:[NSString stringWithFormat:@"Setup:/Network/Interface/%@/AirPort", bsdInterface]]; + if (airportDict) { + NSNumber *x = [self speedForAirport]; + if (x) { + return x; + } + } + } + { + NSNumber *x = [self speedForInterfaceNameViaIOKit:bsdInterface]; + if (x) { + return x; + } + } + { + NSNumber *x = [self speedForInterfaceNameViaIfConfig:bsdInterface]; + if (x) { + return x; + } + } + return [NSNumber numberWithLong:kInterfaceDefaultSpeed]; } -- (NSNumber*)speedForAirport -{ - NSString*line=[self runCommand:@"/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I | grep maxRate"]; - NSRange r=[line rangeOfString:@":"]; - if(r.location==NSNotFound){ - return nil; - } - line=[line substringFromIndex:r.location+1]; - return [NSNumber numberWithDouble:[line doubleValue]*1000*1000]; + +- (NSNumber *)speedForAirport { + NSString *line = [self runCommand:@"/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I | grep maxRate"]; + NSRange r = [line rangeOfString:@":"]; + if (r.location == NSNotFound) { + return nil; + } + line = [line substringFromIndex:r.location + 1]; + return [NSNumber numberWithDouble:[line doubleValue] * 1000 * 1000]; } + - (NSNumber *)speedForInterfaceNameViaIfConfig:(NSString *)bsdInterface { - if (!bsdInterface) return [NSNumber numberWithLong:kInterfaceDefaultSpeed]; - NSLog(@"getting the speed for %@",bsdInterface); - /* The old way to get the speed via IOKit no longer reliably works, most probably due to the slow move to DriverKit. - The link speed as reported by NetworkUtility.app can also be obtained by ifconfig, whose source code is available at - https://opensource.apple.com/source/network_cmds/network_cmds-596/ifconfig.tproj/ - e.g. for Catalina. Unfortunately the ioctl used there is not exposed in the standard development headers, although you can presumably use it by copying the content of the private headers. - Here instead I just directly call ifconfig. - */ - NSString*line=[self runCommand:[NSString stringWithFormat:@"ifconfig -v %@ | egrep 'link rate|uplink'",bsdInterface]]; - if([line containsString:@"does not"]){ - return [NSNumber numberWithLong:0]; - } - NSRange r=[line rangeOfString:@"/"]; - if(r.location==NSNotFound){ - r=[line rangeOfString:@": "]; - } - if(r.location==NSNotFound){ - return [NSNumber numberWithLong:0]; - } - line=[line substringFromIndex:r.location+1]; - double factor=1; - if((r=[line rangeOfString:@"Gbps"]).location!=NSNotFound){ - factor=1000*1000*1000; - }else if((r=[line rangeOfString:@"Mbps"]).location!=NSNotFound){ - factor=1000*1000; - }else if((r=[line rangeOfString:@"Kbps"]).location!=NSNotFound){ - factor=1000; - }else if((r=[line rangeOfString:@"bps"]).location!=NSNotFound){ - factor=1; - }else{ - factor=0; - } - - line=[line substringToIndex:r.location]; - return [NSNumber numberWithDouble:[line doubleValue]*factor]; + if (!bsdInterface) + return [NSNumber numberWithLong:kInterfaceDefaultSpeed]; + MMLog(@"getting the speed for %@", bsdInterface); + /* The old way to get the speed via IOKit no longer reliably works, most probably due to the slow move to DriverKit. + The link speed as reported by NetworkUtility.app can also be obtained by ifconfig, whose source code is available at + https://opensource.apple.com/source/network_cmds/network_cmds-596/ifconfig.tproj/ + e.g. for Catalina. Unfortunately the ioctl used there is not exposed in the standard development headers, although you can presumably use it by copying the content of the private headers. + Here instead I just directly call ifconfig. + */ + NSString *line = [self runCommand:[NSString stringWithFormat:@"ifconfig -v %@ | egrep 'link rate|uplink'", bsdInterface]]; + if ([line containsString:@"does not"]) { + return [NSNumber numberWithInt:0]; + } + NSRange r = [line rangeOfString:@"/"]; + if (r.location == NSNotFound) { + r = [line rangeOfString:@": "]; + } + if (r.location == NSNotFound) { + return [NSNumber numberWithLong:0]; + } + line = [line substringFromIndex:r.location + 1]; + double factor = 1; + if ((r = [line rangeOfString:@"Gbps"]).location != NSNotFound) { + factor = 1000 * 1000 * 1000; + } + else if ((r = [line rangeOfString:@"Mbps"]).location != NSNotFound) { + factor = 1000 * 1000; + } + else if ((r = [line rangeOfString:@"Kbps"]).location != NSNotFound) { + factor = 1000; + } + else if ((r = [line rangeOfString:@"bps"]).location != NSNotFound) { + factor = 1; + } + else { + factor = 0; + } + + line = [line substringToIndex:r.location]; + return [NSNumber numberWithDouble:[line doubleValue] * factor]; } + - (NSNumber *)speedForInterfaceNameViaIOKit:(NSString *)bsdInterface { // Get the speed from IOKit io_iterator_t iterator; @@ -695,15 +733,16 @@ - (NSNumber *)speedForInterfaceNameViaIOKit:(NSString *)bsdInterface { IOBSDNameMatching(masterPort, kNilOptions, [bsdInterface UTF8String]), &iterator); // If we didn't get an iterator guess 10Mbit - if (!iterator) return nil; + if (!iterator) + return nil; // Otherwise poke around IOKit - io_registry_entry_t regEntry = IOIteratorNext(iterator); + io_registry_entry_t regEntry = IOIteratorNext(iterator); if (!regEntry) { IOObjectRelease(iterator); return [NSNumber numberWithLong:kInterfaceDefaultSpeed]; } - io_object_t controllerService = 0; + io_object_t controllerService = 0; IORegistryEntryGetParentEntry(regEntry, kIOServicePlane, &controllerService); if (!controllerService) { IOObjectRelease(regEntry); @@ -719,13 +758,13 @@ - (NSNumber *)speedForInterfaceNameViaIOKit:(NSString *)bsdInterface { IOObjectRelease(iterator); if (linkSpeed && ([linkSpeed unsignedLongLongValue] > 0)) { return linkSpeed; - } else { - return nil; + } + else { + return nil; } } // speedForInterfaceName - (NSDictionary *)sysconfigValueForKey:(NSString *)key { - return (NSDictionary *)CFBridgingRelease(SCDynamicStoreCopyValue(scSession, (CFStringRef)key)); } // sysconfigValueForKey diff --git a/MenuExtras/MenuMeterNet/MenuMeterNetExtra.h b/MenuExtras/MenuMeterNet/MenuMeterNetExtra.h index 3d94f2a7..1e190b20 100644 --- a/MenuExtras/MenuMeterNet/MenuMeterNetExtra.h +++ b/MenuExtras/MenuMeterNet/MenuMeterNetExtra.h @@ -1,64 +1,64 @@ // // MenuMeterNetExtra.h // -// Menu Extra implementation +// Menu Extra implementation // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -#import -#import -#import "MenuMeters.h" #import "MenuMeterDefaults.h" #import "MenuMeterNet.h" #import "MenuMeterNetConfig.h" -#import "MenuMeterNetStats.h" #import "MenuMeterNetPPP.h" +#import "MenuMeterNetStats.h" #import "MenuMeterWorkarounds.h" - +#import "MenuMeters.h" +#import +#import @interface MenuMeterNetExtra : NSMenuExtra { // Menu Extra necessities - NSMenu *extraMenu; + NSMenu *extraMenu; // Pref object - MenuMeterDefaults *ourPrefs; + MenuMeterDefaults *ourPrefs; // Info gatherers/controllers - MenuMeterNetConfig *netConfig; - MenuMeterNetStats *netStats; - MenuMeterNetPPP *pppControl; + MenuMeterNetConfig *netConfig; + MenuMeterNetStats *netStats; + MenuMeterNetPPP *pppControl; // Formatters for localization - NSNumberFormatter *bytesFormatter, *prettyIntFormatter; + NSNumberFormatter *bytesFormatter, *prettyIntFormatter; // Cached colors - NSColor *txColor, *rxColor, *inactiveColor; + NSColor *txColor, *rxColor, *inactiveColor; // Cached bezier paths - NSBezierPath *upArrow, *downArrow; + NSBezierPath *upArrow, *downArrow; // Cached prerendered text - NSImage *throughputLabel, *inactiveThroughputLabel; + NSImage *throughputLabel, *inactiveThroughputLabel; // The length of the menu item - float menuWidth; + float menuWidth; // Historical data samples and current interface config - NSDate *lastSampleDate; - NSMutableArray *netHistoryData, *netHistoryIntervals; - NSDictionary *preferredInterfaceConfig; + NSDate *lastSampleDate; + NSMutableArray *netHistoryData, *netHistoryIntervals; + NSDictionary *preferredInterfaceConfig; // Cached dictionary of menu items that can be updated - NSMutableDictionary *updateMenuItems; - NSFont *throughputFont; + NSMutableDictionary *updateMenuItems; + NSFont *throughputFont; + BOOL tallMenuBar; } // MenuMeterNetExtra diff --git a/MenuExtras/MenuMeterNet/MenuMeterNetExtra.m b/MenuExtras/MenuMeterNet/MenuMeterNetExtra.m index f0386d27..d13b8195 100644 --- a/MenuExtras/MenuMeterNet/MenuMeterNetExtra.m +++ b/MenuExtras/MenuMeterNet/MenuMeterNetExtra.m @@ -1,32 +1,31 @@ // // MenuMeterNetExtra.m // -// Menu Extra implementation +// Menu Extra implementation // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #import "MenuMeterNetExtra.h" - /////////////////////////////////////////////////////////////// // -// Private methods and constants +// Private methods and constants // /////////////////////////////////////////////////////////////// @@ -36,115 +35,131 @@ @interface MenuMeterNetExtra (PrivateMethods) // Image renderers -- (void)renderGraphIntoImage:(NSImage *)image; -- (void)renderActivityIntoImage:(NSImage *)image; -- (void)renderThroughputIntoImage:(NSImage *)image; + +- (void)renderGraphImageSize:(NSSize)imageSize; + +- (void)renderActivityImageSize:(NSSize)imageSize; + +- (void)renderThroughputImageSize:(NSSize)imageSize; // Timer callbacks + - (void)updateMenuWhenDown; // Menu actions + - (void)openNetworkUtil:(id)sender; + - (void)openNetworkPrefs:(id)sender; + - (void)openInternetConnect:(id)sender; + - (void)switchDisplay:(id)sender; + - (void)copyAddress:(id)sender; + - (void)pppConnect:(id)sender; + - (void)pppDisconnect:(id)sender; // Prefs + - (void)configFromPrefs:(NSNotification *)notification; // Data formatting + - (NSString *)throughputStringForBytesPerSecond:(double)bps; + - (NSString *)throughputStringForBytes:(double)bytes inInterval:(NSTimeInterval)interval; -- (NSString *)menubarThroughputStringForBytes:(double)bytes inInterval:(NSTimeInterval)interval; -- (NSString *)throughputStringForBytesPerSecond:(double)bps withSpace:(Boolean)wantSpace; + - (NSString *)trafficStringForNumber:(NSNumber *)throughputNumber withLabel:(NSString *)directionLabel; + - (NSUInteger)scaleDown:(double *)num usingBase:(NSUInteger)base withLimit:(NSUInteger)limit; + - (NSString *)stringifyNumber:(double)num withUnitLabel:(NSString *)label andFormat:(NSString *)format; + - (NSString *)throughputStringForBytes:(NSNumber *)throughputNumber; @end /////////////////////////////////////////////////////////////// // -// Localized strings +// Localized strings // /////////////////////////////////////////////////////////////// -#define kTxLabel @"Tx:" -#define kRxLabel @"Rx:" -#define kPPPTitle @"PPP:" -#define kTCPIPTitle @"TCP/IP:" -#define kIPv4Title @"IPv4:" -#define kIPv6Title @"IPv6:" -#define kTCPIPInactiveTitle @"Inactive" -#define kAppleTalkTitle @"AppleTalk:" -#define kAppleTalkFormat @"Net: %@ Node: %@ Zone: %@" -#define kThroughputTitle @"Throughput:" -#define kPeakThroughputTitle @"Peak Throughput:" -#define kTrafficTotalTitle @"Traffic Totals:" -#define kOpenNetworkUtilityTitle @"Open Network Utility" -#define kOpenNetworkPrefsTitle @"Open Network Preferences" -#define kOpenInternetConnectTitle @"Open Internet Connect" -#define kSelectPrimaryInterfaceTitle @"Display primary interface" -#define kSelectInterfaceTitle @"Display this interface" -#define kCopyIPv4Title @"Copy IPv4 address" -#define kCopyIPv6Title @"Copy IPv6 address" -#define kResetTrafficTotalsTitle @"Reset traffic totals" -#define kPPPConnectTitle @"Connect" -#define kPPPDisconnectTitle @"Disconnect" -#define kNoInterfaceErrorMessage @"No Active Interfaces" -#define kBitsLabel @"bits" -#define kBytesLabel @"bytes" -#define kBitLabel @"b" -#define kKbLabel @"Kb" -#define kMbLabel @"Mb" -#define kGbLabel @"Gb" -#define kTbLabel @"Tb" -#define kByteLabel @"B" -#define kKBLabel @"KB" -#define kMBLabel @"MB" -#define kGBLabel @"GB" -#define kTBLabel @"TB" -#define kBpsLabel @"bps" -#define kKbpsLabel @"Kbps" -#define kMbpsLabel @"Mbps" -#define kGbpsLabel @"Gbps" -#define kBitPerSecondLabel @"b/s" -#define kKbPerSecondLabel @"Kb/s" -#define kMbPerSecondLabel @"Mb/s" -#define kGbPerSecondLabel @"Gb/s" -#define kBytePerSecondLabel @"B/s" -#define kKBPerSecondLabel @"KB/s" -#define kMBPerSecondLabel @"MB/s" -#define kGBPerSecondLabel @"GB/s" -#define kPPPNoConnectTitle @"Not Connected" -#define kPPPConnectingTitle @"Connecting..." -#define kPPPConnectedTitle @"Connected" -#define kPPPConnectedWithTimeTitle @"Connected %02d:%02d:%02d" -#define kPPPDisconnectingTitle @"Disconnecting..." -#define kKiloBinary 1024 -#define kKiloDecimal 1000 +#define kTxLabel @"Tx:" +#define kRxLabel @"Rx:" +#define kPPPTitle @"PPP:" +#define kTCPIPTitle @"TCP/IP:" +#define kIPv4Title @"IPv4:" +#define kIPv6Title @"IPv6:" +#define kTCPIPInactiveTitle @"Inactive" +#define kAppleTalkTitle @"AppleTalk:" +#define kAppleTalkFormat @"Net: %@ Node: %@ Zone: %@" +#define kThroughputTitle @"Throughput:" +#define kPeakThroughputTitle @"Peak Throughput:" +#define kTrafficTotalTitle @"Traffic Totals:" +#define kOpenNetworkUtilityTitle @"Open Network Utility" +#define kOpenNetworkPrefsTitle @"Open Network Preferences" +#define kOpenInternetConnectTitle @"Open Internet Connect" +#define kSelectPrimaryInterfaceTitle @"Display primary interface" +#define kSelectInterfaceTitle @"Display this interface" +#define kCopyIPv4Title @"Copy IPv4 address" +#define kCopyIPv6Title @"Copy IPv6 address" +#define kResetTrafficTotalsTitle @"Reset traffic totals" +#define kPPPConnectTitle @"Connect" +#define kPPPDisconnectTitle @"Disconnect" +#define kNoInterfaceErrorMessage @"No Active Interfaces" +#define kBitsLabel @"bits" +#define kBytesLabel @"bytes" +#define kBitLabel @"b" +#define kKbLabel @"Kb" +#define kMbLabel @"Mb" +#define kGbLabel @"Gb" +#define kTbLabel @"Tb" +#define kByteLabel @"B" +#define kKBLabel @"KB" +#define kMBLabel @"MB" +#define kGBLabel @"GB" +#define kTBLabel @"TB" +#define kBpsLabel @"bps" +#define kKbpsLabel @"Kbps" +#define kMbpsLabel @"Mbps" +#define kGbpsLabel @"Gbps" +#define kBitPerSecondLabel @"b/s" +#define kKbPerSecondLabel @"Kb/s" +#define kMbPerSecondLabel @"Mb/s" +#define kGbPerSecondLabel @"Gb/s" +#define kBytePerSecondLabel @"B/s" +#define kKBPerSecondLabel @"KB/s" +#define kMBPerSecondLabel @"MB/s" +#define kGBPerSecondLabel @"GB/s" +#define kPPPNoConnectTitle @"Not Connected" +#define kPPPConnectingTitle @"Connecting..." +#define kPPPConnectedTitle @"Connected" +#define kPPPConnectedWithTimeTitle @"Connected %02d:%02d:%02d" +#define kPPPDisconnectingTitle @"Disconnecting..." +#define kKiloBinary 1024 +#define kKiloDecimal 1000 /////////////////////////////////////////////////////////////// // -// init/unload/dealloc +// init/unload/dealloc // /////////////////////////////////////////////////////////////// @implementation MenuMeterNetExtra -- init { +- (instancetype)init { - self = [super initWithBundleID:kNetMenuBundleID]; + self = [super initWithBundleID:kNetMenuBundleID]; if (!self) { return nil; } - ourPrefs = [MenuMeterDefaults sharedMenuMeterDefaults]; - if (!ourPrefs) { + ourPrefs = [MenuMeterDefaults sharedMenuMeterDefaults]; + if (!ourPrefs) { NSLog(@"MenuMeterCPU unable to connect to preferences. Abort."); return nil; } @@ -168,12 +183,17 @@ @implementation MenuMeterNetExtra // Disable menu autoenabling [extraMenu setAutoenablesItems:NO]; - // Menu is regenerated in the menu method always so no futher setup - - // Set the menu extra view up - - throughputFont = [NSFont monospacedDigitSystemFontOfSize:9.5f weight:NSFontWeightRegular]; - + // TODO: move the following into MenuMetersPref ?? + CGFloat menuBarHeight = [[NSApp mainMenu] menuBarHeight]; + if (menuBarHeight > 23) { // on MacBooks with notch. (TODO: or when "Menu bar size" is set to "large" system preferences?) + NSArray *screens = NSScreen.screens; + tallMenuBar = screens.count == 1; // If there is a screen attached, it has its own (small) menu and I can’t distinguish the two right now. + } + throughputFont = [NSFont monospacedDigitSystemFontOfSize:tallMenuBar ? 12 : 9.5 weight:NSFontWeightRegular]; + NSFont *traitFont = [NSFontManager.sharedFontManager convertFont:throughputFont toHaveTrait:NSCondensedFontMask]; + if (traitFont) { + throughputFont = traitFont; + } // Set up a NumberFormatter for localization. This is based on code contributed by Mike Fischer // (mike.fischer at fi-works.de) for use in MenuMeters. @@ -191,50 +211,54 @@ @implementation MenuMeterNetExtra // And configure directly from prefs on first load [self configFromPrefs:nil]; - // And hand ourself back to SystemUIServer + // And hand ourself back to SystemUIServer NSLog(@"MenuMeterNet loaded."); - return self; + return self; } // initWithBundle - // dealloc +// dealloc /////////////////////////////////////////////////////////////// // -// NSMenuExtra view callbacks +// NSMenuExtra view callbacks // /////////////////////////////////////////////////////////////// - (NSImage *)image { - [self setupAppearance]; - - // Image to render into (and return to view) - NSImage *currentImage = [[NSImage alloc] initWithSize:NSMakeSize((float)menuWidth, - self.height-1)]; - if (!currentImage) return nil; + [self setupAppearance]; // Don't render without data - if (![netHistoryData count]) return nil; - - int netDisplayModePrefs = [ourPrefs netDisplayMode]; - // Draw displays - if (netDisplayModePrefs & kNetDisplayGraph) { - [self renderGraphIntoImage:currentImage]; - } - if (netDisplayModePrefs & kNetDisplayArrows) { - [self renderActivityIntoImage:currentImage]; - } - if (netDisplayModePrefs & kNetDisplayThroughput) { - [self renderThroughputIntoImage:currentImage]; - } + if (![netHistoryData count]) + return nil; + // Image to render into (and return to view) + NSSize imageSize = NSMakeSize(menuWidth, self.height); + int netDisplayModePrefs = [ourPrefs netDisplayMode]; + + NSImage *currentImage = [NSImage imageWithSize:imageSize + flipped:NO + drawingHandler:^BOOL(NSRect dstRect) { + // Draw displays + if (netDisplayModePrefs & kNetDisplayGraph) { + [self renderGraphImageSize:imageSize]; + } + if (netDisplayModePrefs & kNetDisplayArrows) { + [self renderActivityImageSize:imageSize]; + } + if (netDisplayModePrefs & kNetDisplayThroughput) { + [self renderThroughputImageSize:imageSize]; + } + return YES; + }]; // Send it back for the view to render return currentImage; } // image // Boy does this need refactoring... *sigh* + - (NSMenu *)menu { // New cache @@ -265,34 +289,37 @@ - (NSMenu *)menu { NSString *speed = nil; // Best guess if this is an active interface, default to assume it is active BOOL isActiveInterface = YES; - - if ([details objectForKey:@"linkactive"]) { + + if ([details objectForKey:@"linkactive"]) { isActiveInterface = [[details objectForKey:@"linkactive"] boolValue]; } - - if ([details objectForKey:@"pppstatus"]) { + + if ([details objectForKey:@"pppstatus"]) { if ([(NSNumber *)[[details objectForKey:@"pppstatus"] objectForKey:@"status"] unsignedIntValue] == PPP_IDLE) { isActiveInterface = NO; } } - - // Calc speed + + // Calc speed if ([details objectForKey:@"linkspeed"] && isActiveInterface) { if ([[details objectForKey:@"linkspeed"] doubleValue] < 0) { speed = nil; - } else if ([[details objectForKey:@"linkspeed"] doubleValue] > 1000000000) { + } + else if ([[details objectForKey:@"linkspeed"] doubleValue] > 1000000000) { speed = [NSString stringWithFormat:@" %.0f %@", - ([[details objectForKey:@"linkspeed"] doubleValue] / 1000000000), - [localizedStrings objectForKey:kGbpsLabel]]; - } else if ([[details objectForKey:@"linkspeed"] doubleValue] > 1000000) { + ([[details objectForKey:@"linkspeed"] doubleValue] / 1000000000), + [localizedStrings objectForKey:kGbpsLabel]]; + } + else if ([[details objectForKey:@"linkspeed"] doubleValue] > 1000000) { speed = [NSString stringWithFormat:@" %.0f %@", - ([[details objectForKey:@"linkspeed"] doubleValue] / 1000000), - [localizedStrings objectForKey:kMbpsLabel]]; - } else { + ([[details objectForKey:@"linkspeed"] doubleValue] / 1000000), + [localizedStrings objectForKey:kMbpsLabel]]; + } + else { speed = [NSString stringWithFormat:@" %@ %@", - [bytesFormatter stringForObjectValue: - [NSNumber numberWithDouble:([[details objectForKey:@"linkspeed"] doubleValue] / 1000)]], - [localizedStrings objectForKey:kKbpsLabel]]; + [bytesFormatter stringForObjectValue: + [NSNumber numberWithDouble:([[details objectForKey:@"linkspeed"] doubleValue] / 1000)]], + [localizedStrings objectForKey:kKbpsLabel]]; } } // Weird string cat because some of these values may not be present @@ -302,23 +329,23 @@ - (NSMenu *)menu { // If there is a PPP name use it too if ([details objectForKey:@"devicepppname"]) { interfaceDescription = [NSString stringWithFormat:@"%@ (%@, %@)", - interfaceDescription, - [details objectForKey:@"devicename"], - [details objectForKey:@"devicepppname"]]; - } else { + interfaceDescription, + [details objectForKey:@"devicename"], + [details objectForKey:@"devicepppname"]]; + } + else { interfaceDescription = [NSString stringWithFormat:@"%@ (%@)", - interfaceDescription, - [details objectForKey:@"devicename"]]; + interfaceDescription, + [details objectForKey:@"devicename"]]; } } if (speed || [details objectForKey:@"connectiontype"]) { interfaceDescription = [NSString stringWithFormat:@"%@ -%@%@", - interfaceDescription, - ([details objectForKey:@"connectiontype"] ? - [NSString stringWithFormat:@" %@", [details objectForKey:@"connectiontype"]] : @""), - (speed ? speed : @"")]; + interfaceDescription, + ([details objectForKey:@"connectiontype"] ? [NSString stringWithFormat:@" %@", [details objectForKey:@"connectiontype"]] : @""), + (speed ? speed : @"")]; } - NSMenuItem *titleItem = (NSMenuItem *)[extraMenu addItemWithTitle:interfaceDescription action:nil keyEquivalent:@""]; + NSMenuItem *titleItem = [extraMenu addItemWithTitle:interfaceDescription action:nil keyEquivalent:@""]; // PPP Status if ([details objectForKey:@"pppstatus"]) { // PPP is present @@ -330,17 +357,18 @@ - (NSMenu *)menu { [NSString stringWithFormat:@"%@:", [details objectForKey:@"connectiontype"]]] action:nil keyEquivalent:@""] setEnabled:NO]; - } else { + } + else { [[extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuIndentFormat, [localizedStrings objectForKey:kPPPTitle]] action:nil keyEquivalent:@""] setEnabled:NO]; } switch ([(NSNumber *)[[details objectForKey:@"pppstatus"] objectForKey:@"status"] unsignedIntValue]) { case PPP_IDLE: - pppStatusItem = (NSMenuItem *)[extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuDoubleIndentFormat, - [localizedStrings objectForKey:kPPPNoConnectTitle]] - action:nil - keyEquivalent:@""]; + pppStatusItem = [extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuDoubleIndentFormat, + [localizedStrings objectForKey:kPPPNoConnectTitle]] + action:nil + keyEquivalent:@""]; break; case PPP_INITIALIZE: case PPP_CONNECTLINK: @@ -352,10 +380,10 @@ - (NSMenu *)menu { case PPP_HOLDOFF: case PPP_ONHOLD: case PPP_WAITONBUSY: - pppStatusItem = (NSMenuItem *)[extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuDoubleIndentFormat, - [localizedStrings objectForKey:kPPPConnectingTitle]] - action:nil - keyEquivalent:@""]; + pppStatusItem = [extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuDoubleIndentFormat, + [localizedStrings objectForKey:kPPPConnectingTitle]] + action:nil + keyEquivalent:@""]; break; case PPP_RUNNING: if ([[details objectForKey:@"pppstatus"] objectForKey:@"timeElapsed"]) { @@ -364,24 +392,25 @@ - (NSMenu *)menu { secs %= (60 * 60); uint32_t mins = secs / 60; secs %= 60; - pppStatusItem = (NSMenuItem *)[extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuDoubleIndentFormat, - [NSString stringWithFormat: - [localizedStrings objectForKey:kPPPConnectedWithTimeTitle], - hours, mins, secs]] - action:nil - keyEquivalent:@""]; - } else { - pppStatusItem = (NSMenuItem *)[extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuDoubleIndentFormat, kPPPConnectedTitle] - action:nil - keyEquivalent:@""]; + pppStatusItem = [extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuDoubleIndentFormat, + [NSString stringWithFormat: + [localizedStrings objectForKey:kPPPConnectedWithTimeTitle], + hours, mins, secs]] + action:nil + keyEquivalent:@""]; + } + else { + pppStatusItem = [extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuDoubleIndentFormat, kPPPConnectedTitle] + action:nil + keyEquivalent:@""]; } break; case PPP_TERMINATE: case PPP_DISCONNECTLINK: - pppStatusItem = (NSMenuItem *)[extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuIndentFormat, - [localizedStrings objectForKey:kPPPDisconnectingTitle]] - action:nil - keyEquivalent:@""]; + pppStatusItem = [extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuIndentFormat, + [localizedStrings objectForKey:kPPPDisconnectingTitle]] + action:nil + keyEquivalent:@""]; break; }; if (pppStatusItem) { @@ -413,7 +442,8 @@ - (NSMenu *)menu { action:nil keyEquivalent:@""] setEnabled:NO]; } - } else if ([[details objectForKey:@"ipv4addresses"] count]) { + } + else if ([[details objectForKey:@"ipv4addresses"] count]) { NSEnumerator *addressEnum = [[details objectForKey:@"ipv4addresses"] objectEnumerator]; NSString *address = nil; while ((address = [addressEnum nextObject])) { @@ -421,23 +451,24 @@ - (NSMenu *)menu { action:nil keyEquivalent:@""] setEnabled:NO]; } - } else { + } + else { [[extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuDoubleIndentFormat, - [localizedStrings objectForKey:kTCPIPInactiveTitle]] + [localizedStrings objectForKey:kTCPIPInactiveTitle]] action:nil keyEquivalent:@""] setEnabled:NO]; } // AppleTalk if ([details objectForKey:@"appletalknetid"]) { [[extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuIndentFormat, - [localizedStrings objectForKey:kAppleTalkTitle]] + [localizedStrings objectForKey:kAppleTalkTitle]] action:nil keyEquivalent:@""] setEnabled:NO]; [[extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuDoubleIndentFormat, - [NSString stringWithFormat:[localizedStrings objectForKey:kAppleTalkFormat], - [details objectForKey:@"appletalknetid"], - [details objectForKey:@"appletalknodeid"], - [details objectForKey:@"appletalkzone"]]] + [NSString stringWithFormat:[localizedStrings objectForKey:kAppleTalkFormat], + [details objectForKey:@"appletalknetid"], + [details objectForKey:@"appletalknodeid"], + [details objectForKey:@"appletalkzone"]]] action:nil keyEquivalent:@""] setEnabled:NO]; } @@ -450,7 +481,8 @@ - (NSMenu *)menu { if ([details objectForKey:@"devicepppname"] && ![[details objectForKey:@"devicename"] hasPrefix:@"en"]) { throughputInterface = [details objectForKey:@"devicepppname"]; throughputDetails = [[netHistoryData lastObject] objectForKey:[details objectForKey:@"devicepppname"]]; - } else { + } + else { throughputInterface = [details objectForKey:@"devicename"]; throughputDetails = [[netHistoryData lastObject] objectForKey:[details objectForKey:@"devicename"]]; } @@ -463,22 +495,22 @@ - (NSMenu *)menu { [[extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuIndentFormat, [localizedStrings objectForKey:kThroughputTitle]] action:nil keyEquivalent:@""] setEnabled:NO]; - NSMenuItem *throughputItem = (NSMenuItem *)[extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuDoubleIndentFormat, - [NSString stringWithFormat:@"%@ %@", - [localizedStrings objectForKey:kTxLabel], - [self throughputStringForBytes:[throughputOutNumber doubleValue] - inInterval:[sampleIntervalNum doubleValue]]]] - action:nil - keyEquivalent:@""]; + NSMenuItem *throughputItem = [extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuDoubleIndentFormat, + [NSString stringWithFormat:@"%@ %@", + [localizedStrings objectForKey:kTxLabel], + [self throughputStringForBytes:[throughputOutNumber doubleValue] + inInterval:[sampleIntervalNum doubleValue]]]] + action:nil + keyEquivalent:@""]; [throughputItem setEnabled:NO]; [interfaceUpdateMenuItems setObject:throughputItem forKey:@"deltaoutitem"]; - throughputItem = (NSMenuItem *)[extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuDoubleIndentFormat, - [NSString stringWithFormat:@"%@ %@", - [localizedStrings objectForKey:kRxLabel], - [self throughputStringForBytes:[throughputInNumber doubleValue] - inInterval:[sampleIntervalNum doubleValue]]]] - action:nil - keyEquivalent:@""]; + throughputItem = [extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuDoubleIndentFormat, + [NSString stringWithFormat:@"%@ %@", + [localizedStrings objectForKey:kRxLabel], + [self throughputStringForBytes:[throughputInNumber doubleValue] + inInterval:[sampleIntervalNum doubleValue]]]] + action:nil + keyEquivalent:@""]; [throughputItem setEnabled:NO]; [interfaceUpdateMenuItems setObject:throughputItem forKey:@"deltainitem"]; } @@ -488,10 +520,10 @@ - (NSMenu *)menu { [[extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuIndentFormat, [localizedStrings objectForKey:kPeakThroughputTitle]] action:nil keyEquivalent:@""] setEnabled:NO]; - NSMenuItem *peakItem = (NSMenuItem *)[extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuDoubleIndentFormat, - [self throughputStringForBytesPerSecond:[peakNumber doubleValue]]] - action:nil - keyEquivalent:@""]; + NSMenuItem *peakItem = [extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuDoubleIndentFormat, + [self throughputStringForBytesPerSecond:[peakNumber doubleValue]]] + action:nil + keyEquivalent:@""]; [peakItem setEnabled:NO]; [interfaceUpdateMenuItems setObject:peakItem forKey:@"peakitem"]; } @@ -502,16 +534,18 @@ - (NSMenu *)menu { [[extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuIndentFormat, [localizedStrings objectForKey:kTrafficTotalTitle]] action:nil keyEquivalent:@""] setEnabled:NO]; - NSMenuItem *totalItem = (NSMenuItem *)[extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuDoubleIndentFormat, - [self trafficStringForNumber:throughputOutNumber withLabel:[localizedStrings objectForKey:kTxLabel]]] - action:nil - keyEquivalent:@""]; + NSMenuItem *totalItem = [extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuDoubleIndentFormat, + [self trafficStringForNumber:throughputOutNumber + withLabel:[localizedStrings objectForKey:kTxLabel]]] + action:nil + keyEquivalent:@""]; [totalItem setEnabled:NO]; [interfaceUpdateMenuItems setObject:totalItem forKey:@"totaloutitem"]; - totalItem = (NSMenuItem *)[extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuDoubleIndentFormat, - [self trafficStringForNumber:throughputInNumber withLabel:[localizedStrings objectForKey:kRxLabel]]] - action:nil - keyEquivalent:@""]; + totalItem = [extraMenu addItemWithTitle:[NSString stringWithFormat:kMenuDoubleIndentFormat, + [self trafficStringForNumber:throughputInNumber + withLabel:[localizedStrings objectForKey:kRxLabel]]] + action:nil + keyEquivalent:@""]; [totalItem setEnabled:NO]; [interfaceUpdateMenuItems setObject:totalItem forKey:@"totalinitem"]; } @@ -535,9 +569,9 @@ - (NSMenu *)menu { NSMenuItem *pppControlItem = nil; switch ([(NSNumber *)[[details objectForKey:@"pppstatus"] objectForKey:@"status"] unsignedIntValue]) { case PPP_IDLE: - pppControlItem = (NSMenuItem *)[interfaceSubmenu addItemWithTitle:[localizedStrings objectForKey:kPPPConnectTitle] - action:@selector(pppConnect:) - keyEquivalent:@""]; + pppControlItem = [interfaceSubmenu addItemWithTitle:[localizedStrings objectForKey:kPPPConnectTitle] + action:@selector(pppConnect:) + keyEquivalent:@""]; break; case PPP_INITIALIZE: case PPP_CONNECTLINK: @@ -550,43 +584,44 @@ - (NSMenu *)menu { case PPP_ONHOLD: case PPP_WAITONBUSY: case PPP_RUNNING: - pppControlItem = (NSMenuItem *)[interfaceSubmenu addItemWithTitle:[localizedStrings objectForKey:kPPPDisconnectTitle] - action:@selector(pppDisconnect:) - keyEquivalent:@""]; + pppControlItem = [interfaceSubmenu addItemWithTitle:[localizedStrings objectForKey:kPPPDisconnectTitle] + action:@selector(pppDisconnect:) + keyEquivalent:@""]; break; case PPP_TERMINATE: case PPP_DISCONNECTLINK: - pppControlItem = (NSMenuItem *)[interfaceSubmenu addItemWithTitle:[localizedStrings objectForKey:kPPPConnectTitle] - action:@selector(pppConnect:) - keyEquivalent:@""]; + pppControlItem = [interfaceSubmenu addItemWithTitle:[localizedStrings objectForKey:kPPPConnectTitle] + action:@selector(pppConnect:) + keyEquivalent:@""]; break; }; [pppControlItem setTarget:self]; [pppControlItem setRepresentedObject:[details objectForKey:@"service"]]; [interfaceSubmenu addItem:[NSMenuItem separatorItem]]; } - + // Add interface selection submenus BOOL hadInterfaceSelector = NO; if ([[details objectForKey:@"primary"] boolValue]) { - NSMenuItem *primarySwitchItem = (NSMenuItem *)[interfaceSubmenu addItemWithTitle:[localizedStrings objectForKey:kSelectPrimaryInterfaceTitle] - action:@selector(switchDisplay:) - keyEquivalent:@""]; + NSMenuItem *primarySwitchItem = [interfaceSubmenu addItemWithTitle:[localizedStrings objectForKey:kSelectPrimaryInterfaceTitle] + action:@selector(switchDisplay:) + keyEquivalent:@""]; [primarySwitchItem setRepresentedObject:kNetPrimaryInterface]; [primarySwitchItem setTarget:self]; if ([[ourPrefs netPreferInterface] isEqualToString:kNetPrimaryInterface]) { [primarySwitchItem setEnabled:NO]; - } else { + } + else { [primarySwitchItem setEnabled:YES]; } hadInterfaceSelector = YES; } - + // Other choose interface if ([details objectForKey:@"devicename"]) { - NSMenuItem *interfaceSwitchItem = (NSMenuItem *)[interfaceSubmenu addItemWithTitle:[localizedStrings objectForKey:kSelectInterfaceTitle] - action:@selector(switchDisplay:) - keyEquivalent:@""]; + NSMenuItem *interfaceSwitchItem = [interfaceSubmenu addItemWithTitle:[localizedStrings objectForKey:kSelectInterfaceTitle] + action:@selector(switchDisplay:) + keyEquivalent:@""]; [interfaceSwitchItem setRepresentedObject:[details objectForKey:@"devicename"]]; [interfaceSwitchItem setTarget:self]; // Disable if this is preferred @@ -595,58 +630,63 @@ - (NSMenu *)menu { } hadInterfaceSelector = YES; } - - if (hadInterfaceSelector) { + + if (hadInterfaceSelector) { [interfaceSubmenu addItem:[NSMenuItem separatorItem]]; } - + // Checkmark the interface menu if we haven't found one already if ([[ourPrefs netPreferInterface] isEqualToString:kNetPrimaryInterface] && [[details objectForKey:@"primary"] boolValue]) { - // This is the primary and the primary is preferred - [titleItem setState:NSOnState]; - } else if (preferredInterfaceConfig && [details objectForKey:@"devicename"]) { + // This is the primary and the primary is preferred + [titleItem setState:NSOnState]; + } + else if (preferredInterfaceConfig && [details objectForKey:@"devicename"]) { // Is this device the one being graphed? if ([[details objectForKey:@"devicename"] isEqualToString:[preferredInterfaceConfig objectForKey:@"name"]] || [[details objectForKey:@"devicename"] isEqualToString:[preferredInterfaceConfig objectForKey:@"statname"]]) { [titleItem setState:NSOnState]; } - } else if (preferredInterfaceConfig && [details objectForKey:@"devicepppname"]) { + } + else if (preferredInterfaceConfig && [details objectForKey:@"devicepppname"]) { if ([[details objectForKey:@"devicepppname"] isEqualToString:[preferredInterfaceConfig objectForKey:@"name"]] || [[details objectForKey:@"devicepppname"] isEqualToString:[preferredInterfaceConfig objectForKey:@"statname"]]) { - [titleItem setState:NSOnState]; + [titleItem setState:NSOnState]; } } - + // Copy IP - NSMenuItem *copyIPItem = (NSMenuItem *)[interfaceSubmenu addItemWithTitle:[localizedStrings objectForKey:kCopyIPv4Title] - action:@selector(copyAddress:) - keyEquivalent:@""]; + NSMenuItem *copyIPItem = [interfaceSubmenu addItemWithTitle:[localizedStrings objectForKey:kCopyIPv4Title] + action:@selector(copyAddress:) + keyEquivalent:@""]; [copyIPItem setTarget:self]; if ([[details objectForKey:@"ipv4addresses"] count]) { [copyIPItem setRepresentedObject:[details objectForKey:@"ipv4addresses"]]; - } else { + } + else { [copyIPItem setEnabled:NO]; } if ([[details objectForKey:@"ipv6addresses"] count]) { - copyIPItem = (NSMenuItem *)[interfaceSubmenu addItemWithTitle:[localizedStrings objectForKey:kCopyIPv6Title] - action:@selector(copyAddress:) - keyEquivalent:@""]; + copyIPItem = [interfaceSubmenu addItemWithTitle:[localizedStrings objectForKey:kCopyIPv6Title] + action:@selector(copyAddress:) + keyEquivalent:@""]; [copyIPItem setTarget:self]; if ([[details objectForKey:@"ipv6addresses"] count]) { [copyIPItem setRepresentedObject:[details objectForKey:@"ipv6addresses"]]; - } else { + } + else { [copyIPItem setEnabled:NO]; } } - if ([details objectForKey:@"devicename"]) { - NSMenuItem*resetTotals = (NSMenuItem *)[interfaceSubmenu addItemWithTitle:[localizedStrings objectForKey:kResetTrafficTotalsTitle] - action:@selector(resetTotals:) - keyEquivalent:@""]; - [resetTotals setTarget:self]; - [resetTotals setRepresentedObject:[details objectForKey:@"devicename"]]; - } + if ([details objectForKey:@"devicename"]) { + NSMenuItem *resetTotals = [interfaceSubmenu addItemWithTitle:[localizedStrings objectForKey:kResetTrafficTotalsTitle] + action:@selector(resetTotals:) + keyEquivalent:@""]; + [resetTotals setTarget:self]; + [resetTotals setRepresentedObject:[details objectForKey:@"devicename"]]; + } } - } else { + } + else { [[extraMenu addItemWithTitle:[localizedStrings objectForKey:kNoInterfaceErrorMessage] action:nil keyEquivalent:@""] setEnabled:NO]; @@ -675,16 +715,15 @@ - (NSMenu *)menu { /////////////////////////////////////////////////////////////// // -// Image renderers +// Image renderers // /////////////////////////////////////////////////////////////// -- (void)renderGraphIntoImage:(NSImage *)image { +- (void)renderGraphImageSize:(NSSize)imageSize { // Cache style and other values for duration of this method int graphStyle = [ourPrefs netGraphStyle]; BOOL rxOnTop = ([ourPrefs netDisplayOrientation] == kNetDisplayOrientRxTx) ? YES : NO; - NSSize imageSize = [image size]; float graphHeight = (float)floor((imageSize.height - 1) / 2); // Graph paths @@ -692,19 +731,21 @@ - (void)renderGraphIntoImage:(NSImage *)image { NSBezierPath *bottomPath = [NSBezierPath bezierPath]; if ((graphStyle == kNetGraphStyleOpposed) || (graphStyle == kNetGraphStyleInverseOpposed)) { [bottomPath moveToPoint:NSMakePoint(0, 0)]; - [bottomPath lineToPoint:NSMakePoint(0, 0.5f)]; + [bottomPath lineToPoint:NSMakePoint(0, 0.5)]; [topPath moveToPoint:NSMakePoint(0, imageSize.height)]; - [topPath lineToPoint:NSMakePoint(0, imageSize.height - 0.5f)]; - } else if (graphStyle == kNetGraphStyleCentered) { + [topPath lineToPoint:NSMakePoint(0, imageSize.height - 0.5)]; + } + else if (graphStyle == kNetGraphStyleCentered) { [topPath moveToPoint:NSMakePoint(0, graphHeight + 1)]; - [topPath lineToPoint:NSMakePoint(0, graphHeight + 1.5f)]; + [topPath lineToPoint:NSMakePoint(0, graphHeight + 1.5)]; [bottomPath moveToPoint:NSMakePoint(0, graphHeight)]; - [bottomPath lineToPoint:NSMakePoint(0, graphHeight - 0.5f)]; - } else { + [bottomPath lineToPoint:NSMakePoint(0, graphHeight - 0.5)]; + } + else { [topPath moveToPoint:NSMakePoint(0, graphHeight + 1)]; - [topPath lineToPoint:NSMakePoint(0, graphHeight + 1.5f)]; + [topPath lineToPoint:NSMakePoint(0, graphHeight + 1.5)]; [bottomPath moveToPoint:NSMakePoint(0, 0)]; - [bottomPath lineToPoint:NSMakePoint(0, 0.5f)]; + [bottomPath lineToPoint:NSMakePoint(0, 0.5)]; } // Get scale (scale is based on latest primary data, not historical) @@ -712,15 +753,18 @@ - (void)renderGraphIntoImage:(NSImage *)image { switch ([ourPrefs netScaleMode]) { case kNetScaleInterfaceSpeed: if ([preferredInterfaceConfig objectForKey:@"speed"]) { - scaleFactor = [[preferredInterfaceConfig objectForKey:@"speed"] floatValue] / 8; // Convert to bytes + scaleFactor = [[preferredInterfaceConfig objectForKey:@"speed"] floatValue] / 8; // Convert to bytes } break; case kNetScalePeakTraffic: - if (![preferredInterfaceConfig objectForKey:@"statname"]) break; - if (![netHistoryData count]) break; + if (![preferredInterfaceConfig objectForKey:@"statname"]) + break; + if (![netHistoryData count]) + break; NSDictionary *primaryStats = [[netHistoryData objectAtIndex:0] - objectForKey:[preferredInterfaceConfig objectForKey:@"statname"]]; - if (![primaryStats objectForKey:@"peak"]) break; + objectForKey:[preferredInterfaceConfig objectForKey:@"statname"]]; + if (![primaryStats objectForKey:@"peak"]) + break; scaleFactor = [[primaryStats objectForKey:@"peak"] floatValue]; break; } @@ -743,25 +787,31 @@ - (void)renderGraphIntoImage:(NSImage *)image { // Loop over pixels in desired width until we're out of data int renderPosition = 0; - float renderHeight = graphHeight - 0.5f; // Save room for baseline + float renderHeight = graphHeight - 0.5; // Save room for baseline for (renderPosition = 0; renderPosition < [ourPrefs netGraphLength]; renderPosition++) { // No data at this position? if ((renderPosition >= [netHistoryData count]) || - (renderPosition >= [netHistoryIntervals count])) break; + (renderPosition >= [netHistoryIntervals count])) + break; // Can't scale by zero - if (scaleFactor <= 0) continue; + if (scaleFactor <= 0) + continue; // Grab history data NSDictionary *netHistoryEntry = [netHistoryData objectAtIndex:renderPosition]; - if (!netHistoryData) continue; + if (!netHistoryData) + continue; float sampleInterval = [[netHistoryIntervals objectAtIndex:renderPosition] floatValue]; - if (sampleInterval <= 0) continue; + if (sampleInterval <= 0) + continue; // Grab stats for the primary - if (![preferredInterfaceConfig objectForKey:@"statname"]) continue; + if (![preferredInterfaceConfig objectForKey:@"statname"]) + continue; NSDictionary *primaryStats = [netHistoryEntry objectForKey:[preferredInterfaceConfig objectForKey:@"statname"]]; - if (!primaryStats) continue; + if (!primaryStats) + continue; // Calc scaled values float txValue = [[primaryStats objectForKey:@"deltaout"] floatValue] / sampleInterval; @@ -785,105 +835,123 @@ - (void)renderGraphIntoImage:(NSImage *)image { break; } // Bound - if (txValue > 1) { txValue = 1; } - if (rxValue > 1) { rxValue = 1; } - if (txValue < 0) { txValue = 0; } - if (rxValue < 0) { rxValue = 0; } + if (txValue > 1) { + txValue = 1; + } + if (rxValue > 1) { + rxValue = 1; + } + if (txValue < 0) { + txValue = 0; + } + if (rxValue < 0) { + rxValue = 0; + } // Update paths if (graphStyle == kNetGraphStyleInverseOpposed) { if (rxOnTop) { - [topPath lineToPoint:NSMakePoint(renderPosition, imageSize.height - (rxValue * renderHeight) - 0.5f)]; - [bottomPath lineToPoint:NSMakePoint(renderPosition, (txValue * renderHeight) + 0.5f)]; - } else { - [topPath lineToPoint:NSMakePoint(renderPosition, imageSize.height - (txValue * renderHeight) - 0.5f)]; - [bottomPath lineToPoint:NSMakePoint(renderPosition, (rxValue * renderHeight) + 0.5f)]; + [topPath lineToPoint:NSMakePoint(renderPosition, imageSize.height - (rxValue * renderHeight) - 0.5)]; + [bottomPath lineToPoint:NSMakePoint(renderPosition, (txValue * renderHeight) + 0.5)]; } - } else if (graphStyle == kNetGraphStyleOpposed) { + else { + [topPath lineToPoint:NSMakePoint(renderPosition, imageSize.height - (txValue * renderHeight) - 0.5)]; + [bottomPath lineToPoint:NSMakePoint(renderPosition, (rxValue * renderHeight) + 0.5)]; + } + } + else if (graphStyle == kNetGraphStyleOpposed) { if (rxOnTop) { - [topPath lineToPoint:NSMakePoint(renderPosition, imageSize.height - (txValue * renderHeight) - 0.5f)]; - [bottomPath lineToPoint:NSMakePoint(renderPosition, (rxValue * renderHeight) + 0.5f)]; - } else { - [topPath lineToPoint:NSMakePoint(renderPosition, imageSize.height - (rxValue * renderHeight) - 0.5f)]; - [bottomPath lineToPoint:NSMakePoint(renderPosition, (txValue * renderHeight) + 0.5f)]; + [topPath lineToPoint:NSMakePoint(renderPosition, imageSize.height - (txValue * renderHeight) - 0.5)]; + [bottomPath lineToPoint:NSMakePoint(renderPosition, (rxValue * renderHeight) + 0.5)]; + } + else { + [topPath lineToPoint:NSMakePoint(renderPosition, imageSize.height - (rxValue * renderHeight) - 0.5)]; + [bottomPath lineToPoint:NSMakePoint(renderPosition, (txValue * renderHeight) + 0.5)]; } - } else if (graphStyle == kNetGraphStyleCentered) { + } + else if (graphStyle == kNetGraphStyleCentered) { if (rxOnTop) { - [topPath lineToPoint:NSMakePoint(renderPosition, (rxValue * renderHeight) + graphHeight + 1.5f)]; - [bottomPath lineToPoint:NSMakePoint(renderPosition, graphHeight - (txValue * renderHeight) - 0.5f)]; - } else { - [topPath lineToPoint:NSMakePoint(renderPosition, (txValue * renderHeight) + graphHeight + 1.5f)]; - [bottomPath lineToPoint:NSMakePoint(renderPosition, graphHeight - (rxValue * renderHeight) - 0.5f)]; + [topPath lineToPoint:NSMakePoint(renderPosition, (rxValue * renderHeight) + graphHeight + 1.5)]; + [bottomPath lineToPoint:NSMakePoint(renderPosition, graphHeight - (txValue * renderHeight) - 0.5)]; + } + else { + [topPath lineToPoint:NSMakePoint(renderPosition, (txValue * renderHeight) + graphHeight + 1.5)]; + [bottomPath lineToPoint:NSMakePoint(renderPosition, graphHeight - (rxValue * renderHeight) - 0.5)]; } - } else { + } + else { if (rxOnTop) { - [topPath lineToPoint:NSMakePoint(renderPosition, (rxValue * renderHeight) + graphHeight + 1.5f)]; - [bottomPath lineToPoint:NSMakePoint(renderPosition, (txValue * renderHeight) + 0.5f)]; - } else { - [topPath lineToPoint:NSMakePoint(renderPosition, (txValue * renderHeight) + graphHeight + 1.5f)]; - [bottomPath lineToPoint:NSMakePoint(renderPosition, (rxValue * renderHeight) + 0.5f)]; + [topPath lineToPoint:NSMakePoint(renderPosition, (rxValue * renderHeight) + graphHeight + 1.5)]; + [bottomPath lineToPoint:NSMakePoint(renderPosition, (txValue * renderHeight) + 0.5)]; + } + else { + [topPath lineToPoint:NSMakePoint(renderPosition, (txValue * renderHeight) + graphHeight + 1.5)]; + [bottomPath lineToPoint:NSMakePoint(renderPosition, (rxValue * renderHeight) + 0.5)]; } } } // Return to lower edge (fill will close the graph) if ((graphStyle == kNetGraphStyleOpposed) || (graphStyle == kNetGraphStyleInverseOpposed)) { - [topPath lineToPoint:NSMakePoint(renderPosition - 1, imageSize.height - 0.5f)]; + [topPath lineToPoint:NSMakePoint(renderPosition - 1, imageSize.height - 0.5)]; [topPath lineToPoint:NSMakePoint(renderPosition - 1, imageSize.height)]; - [bottomPath lineToPoint:NSMakePoint(renderPosition - 1, 0.5f)]; + [bottomPath lineToPoint:NSMakePoint(renderPosition - 1, 0.5)]; [bottomPath lineToPoint:NSMakePoint(renderPosition - 1, 0)]; - } else if (graphStyle == kNetGraphStyleCentered) { - [topPath lineToPoint:NSMakePoint(renderPosition - 1, graphHeight + 1.5f)]; + } + else if (graphStyle == kNetGraphStyleCentered) { + [topPath lineToPoint:NSMakePoint(renderPosition - 1, graphHeight + 1.5)]; [topPath lineToPoint:NSMakePoint(renderPosition - 1, graphHeight + 1)]; - [bottomPath lineToPoint:NSMakePoint(renderPosition - 1, graphHeight - 0.5f)]; + [bottomPath lineToPoint:NSMakePoint(renderPosition - 1, graphHeight - 0.5)]; [bottomPath lineToPoint:NSMakePoint(renderPosition - 1, graphHeight)]; - } else { - [topPath lineToPoint:NSMakePoint(renderPosition - 1, graphHeight + 1.5f)]; + } + else { + [topPath lineToPoint:NSMakePoint(renderPosition - 1, graphHeight + 1.5)]; [topPath lineToPoint:NSMakePoint(renderPosition - 1, graphHeight + 1)]; - [bottomPath lineToPoint:NSMakePoint(renderPosition - 1, 0.5f)]; + [bottomPath lineToPoint:NSMakePoint(renderPosition - 1, 0.5)]; [bottomPath lineToPoint:NSMakePoint(renderPosition - 1, 0)]; } // Draw - [image lockFocus]; if (![preferredInterfaceConfig objectForKey:@"interfaceup"]) { [inactiveColor set]; [topPath fill]; [bottomPath fill]; - } else { + } + else { if (rxOnTop) { [rxColor set]; [topPath fill]; [txColor set]; [bottomPath fill]; - } else { + } + else { [rxColor set]; [bottomPath fill]; [txColor set]; [topPath fill]; } } - [[NSColor blackColor] set]; - [image unlockFocus]; - } // renderGraphIntoImage -- (void)renderActivityIntoImage:(NSImage *)image { +- (void)renderActivityImageSize:(NSSize)imageSize { // Get scale (scale is based on latest primary data, not historical) float scaleFactor = 0; switch ([ourPrefs netScaleMode]) { case kNetScaleInterfaceSpeed: if ([preferredInterfaceConfig objectForKey:@"speed"]) { - scaleFactor = [[preferredInterfaceConfig objectForKey:@"speed"] floatValue] / 8; // Convert to bytes + scaleFactor = [[preferredInterfaceConfig objectForKey:@"speed"] floatValue] / 8; // Convert to bytes } break; case kNetScalePeakTraffic: - if (![preferredInterfaceConfig objectForKey:@"statname"]) break; - if (![netHistoryData count]) break; + if (![preferredInterfaceConfig objectForKey:@"statname"]) + break; + if (![netHistoryData count]) + break; NSDictionary *primaryStats = [[netHistoryData objectAtIndex:0] - objectForKey:[preferredInterfaceConfig objectForKey:@"statname"]]; - if (![primaryStats objectForKey:@"peak"]) break; + objectForKey:[preferredInterfaceConfig objectForKey:@"statname"]]; + if (![primaryStats objectForKey:@"peak"]) + break; scaleFactor = [[primaryStats objectForKey:@"peak"] floatValue]; break; } @@ -934,13 +1002,20 @@ - (void)renderActivityIntoImage:(NSImage *)image { } } // Bound - if (txValue > 1) { txValue = 1; } - if (rxValue > 1) { rxValue = 1; } - if (txValue < 0) { txValue = 0; } - if (rxValue < 0) { rxValue = 0; } + if (txValue > 1) { + txValue = 1; + } + if (rxValue > 1) { + rxValue = 1; + } + if (txValue < 0) { + txValue = 0; + } + if (rxValue < 0) { + rxValue = 0; + } - // Lock on image and draw - [image lockFocus]; + // Draw if ([[preferredInterfaceConfig objectForKey:@"interfaceup"] boolValue]) { if ([ourPrefs netDisplayOrientation] == kNetDisplayOrientRxTx) { [[rxColor colorWithAlphaComponent:rxValue] set]; @@ -951,7 +1026,8 @@ - (void)renderActivityIntoImage:(NSImage *)image { [downArrow fill]; [txColor set]; [downArrow stroke]; - } else { + } + else { [[txColor colorWithAlphaComponent:txValue] set]; [upArrow fill]; [txColor set]; @@ -961,19 +1037,15 @@ - (void)renderActivityIntoImage:(NSImage *)image { [rxColor set]; [downArrow stroke]; } - } else { + } + else { [inactiveColor set]; [upArrow stroke]; [downArrow stroke]; } - - // Reset color and unlock - [[NSColor blackColor] set]; - [image unlockFocus]; - } // renderActivityIntoImage -- (void)renderThroughputIntoImage:(NSImage *)image { +- (void)renderThroughputImageSize:(NSSize)imageSize { // Get the primary stats double txValue = 0; @@ -986,8 +1058,12 @@ - (void)renderThroughputIntoImage:(NSImage *)image { rxValue = [[primaryStats objectForKey:@"deltain"] doubleValue]; } } - if (txValue < 0) { txValue = 0; } - if (rxValue < 0) { rxValue = 0; } + if (txValue < 0) { + txValue = 0; + } + if (rxValue < 0) { + rxValue = 0; + } // Construct strings double sampleInterval = [ourPrefs netInterval]; @@ -995,31 +1071,22 @@ - (void)renderThroughputIntoImage:(NSImage *)image { if (!sampleIntervalNum && ([sampleIntervalNum doubleValue] > 0)) { sampleInterval = [sampleIntervalNum doubleValue]; } - - NSString *txString = [self menubarThroughputStringForBytes:txValue inInterval:sampleInterval]; - NSString *rxString = [self menubarThroughputStringForBytes:rxValue inInterval:sampleInterval]; + NSString *txString = [self throughputStringForBytes:txValue inInterval:sampleInterval]; + NSString *rxString = [self throughputStringForBytes:rxValue inInterval:sampleInterval]; + + NSDictionary *attributes = @{NSFontAttributeName: throughputFont, + NSForegroundColorAttributeName: interfaceUp ? txColor : inactiveColor}; NSAttributedString *renderTxString = [[NSAttributedString alloc] - initWithString:txString - attributes:[NSDictionary dictionaryWithObjectsAndKeys: - throughputFont, - NSFontAttributeName, - interfaceUp ? txColor : inactiveColor, - NSForegroundColorAttributeName, - nil]]; + initWithString:txString + attributes:attributes]; + attributes = @{NSFontAttributeName: throughputFont, + NSForegroundColorAttributeName: interfaceUp ? rxColor : inactiveColor}; NSAttributedString *renderRxString = [[NSAttributedString alloc] - initWithString:rxString - attributes:[NSDictionary dictionaryWithObjectsAndKeys: - throughputFont, - NSFontAttributeName, - interfaceUp ? rxColor : inactiveColor, - NSForegroundColorAttributeName, - nil]]; - - // Draw - [image lockFocus]; + initWithString:rxString + attributes:attributes]; // Draw label if needed - float labelOffset = 0; if ([ourPrefs netThroughputLabel]) { + CGFloat labelOffset = 0; if ([ourPrefs netDisplayMode] & kNetDisplayGraph) { labelOffset += [ourPrefs netGraphLength] + kNetDisplayGapWidth; } @@ -1028,31 +1095,33 @@ - (void)renderThroughputIntoImage:(NSImage *)image { } if (interfaceUp) { [throughputLabel compositeToPoint:NSMakePoint(labelOffset, 0) operation:NSCompositeSourceOver]; - } else { + } + else { [inactiveThroughputLabel compositeToPoint:NSMakePoint(labelOffset, 0) operation:NSCompositeSourceOver]; } } // No descenders, so render lower + NSPoint rxPos; + NSPoint txPos; if ([ourPrefs netDisplayOrientation] == kNetDisplayOrientRxTx) { - [renderRxString drawAtPoint:NSMakePoint((float)ceil(menuWidth - [renderRxString size].width), (float)floor([image size].height / 2) - 1)]; - [renderTxString drawAtPoint:NSMakePoint((float)ceil(menuWidth - [renderTxString size].width), -1)]; + rxPos = NSMakePoint((float)ceil(menuWidth - [renderRxString size].width), floor(imageSize.height / 2) - 1); + txPos = NSMakePoint((float)ceil(menuWidth - [renderTxString size].width), tallMenuBar ? -3 : -1); } else { - [renderTxString drawAtPoint:NSMakePoint((float)ceil(menuWidth - [renderTxString size].width), (float)floor([image size].height / 2) - 1)]; - [renderRxString drawAtPoint:NSMakePoint((float)ceil(menuWidth - [renderRxString size].width), -1)]; + txPos = NSMakePoint((float)ceil(menuWidth - [renderTxString size].width), floor(imageSize.height / 2) - 1); + rxPos = NSMakePoint((float)ceil(menuWidth - [renderRxString size].width), tallMenuBar ? -3 : -1); } - [image unlockFocus]; - + [renderTxString drawAtPoint:txPos]; + [renderRxString drawAtPoint:rxPos]; } // renderThroughputIntoImage /////////////////////////////////////////////////////////////// // -// Timer callbacks +// Timer callbacks // /////////////////////////////////////////////////////////////// - (void)timerFired:(NSTimer *)timer { - // Get new config preferredInterfaceConfig = [netConfig interfaceConfigForInterfaceName:[ourPrefs netPreferInterface]]; @@ -1064,25 +1133,26 @@ - (void)timerFired:(NSTimer *)timer { // Load new net data NSDictionary *netLoad = [netStats netStatsForInterval:currentSampleInterval]; - if(netLoad){ // fix for https://github.com/yujitach/MenuMeters/issues/120 - // Add to history (at least one) - if ([ourPrefs netDisplayMode] & kNetDisplayGraph) { - if ([netHistoryData count] >= [ourPrefs netGraphLength]) { - [netHistoryData removeObjectsInRange:NSMakeRange(0, [netHistoryData count] - [ourPrefs netGraphLength] + 1)]; + if (netLoad) { // fix for https://github.com/yujitach/MenuMeters/issues/120 + // Add to history (at least one) + if ([ourPrefs netDisplayMode] & kNetDisplayGraph) { + if ([netHistoryData count] >= [ourPrefs netGraphLength]) { + [netHistoryData removeObjectsInRange:NSMakeRange(0, [netHistoryData count] - [ourPrefs netGraphLength] + 1)]; + } + if ([netHistoryIntervals count] >= [ourPrefs netGraphLength]) { + [netHistoryIntervals removeObjectsInRange:NSMakeRange(0, [netHistoryIntervals count] - [ourPrefs netGraphLength] + 1)]; + } } - if ([netHistoryIntervals count] >= [ourPrefs netGraphLength]) { - [netHistoryIntervals removeObjectsInRange:NSMakeRange(0, [netHistoryIntervals count] - [ourPrefs netGraphLength] + 1)]; + else { + [netHistoryData removeAllObjects]; + [netHistoryIntervals removeAllObjects]; } - } else { - [netHistoryData removeAllObjects]; - [netHistoryIntervals removeAllObjects]; - } - [netHistoryData addObject:netLoad]; - [netHistoryIntervals addObject:[NSNumber numberWithDouble:currentSampleInterval]]; + [netHistoryData addObject:netLoad]; + [netHistoryIntervals addObject:[NSNumber numberWithDouble:currentSampleInterval]]; - // Update for next sample - lastSampleDate = [NSDate date]; - } + // Update for next sample + lastSampleDate = [NSDate date]; + } // If the menu is down force it to update if (self.isMenuVisible) { [self updateMenuWhenDown]; @@ -1094,11 +1164,13 @@ - (void)timerFired:(NSTimer *)timer { - (void)updateMenuWhenDown { // If no menu items are currently live, do nothing - if (!updateMenuItems) return; + if (!updateMenuItems) + return; // Pull in latest data and iterate, updating existing menu items NSArray *detailsArray = [netConfig interfaceDetails]; - if (![detailsArray count]) return; + if (![detailsArray count]) + return; NSEnumerator *detailsEnum = [detailsArray objectEnumerator]; NSDictionary *details = nil; while ((details = [detailsEnum nextObject])) { @@ -1108,7 +1180,6 @@ - (void)updateMenuWhenDown { } NSDictionary *updateInfoForService = [updateMenuItems objectForKey:[details objectForKey:@"service"]]; - // PPP updates if ([updateInfoForService objectForKey:@"pppstatusitem"]) { NSMenuItem *pppMenuItem = [updateInfoForService objectForKey:@"pppstatusitem"]; @@ -1117,7 +1188,7 @@ - (void)updateMenuWhenDown { LiveUpdateMenuItemTitle(extraMenu, [extraMenu indexOfItem:pppMenuItem], [NSString stringWithFormat:kMenuDoubleIndentFormat, - [localizedStrings objectForKey:kPPPNoConnectTitle]]); + [localizedStrings objectForKey:kPPPNoConnectTitle]]); break; case PPP_INITIALIZE: case PPP_CONNECTLINK: @@ -1132,7 +1203,7 @@ - (void)updateMenuWhenDown { LiveUpdateMenuItemTitle(extraMenu, [extraMenu indexOfItem:pppMenuItem], [NSString stringWithFormat:kMenuDoubleIndentFormat, - [localizedStrings objectForKey:kPPPConnectingTitle]]); + [localizedStrings objectForKey:kPPPConnectingTitle]]); break; case PPP_RUNNING: if ([[details objectForKey:@"pppstatus"] objectForKey:@"timeElapsed"]) { @@ -1144,10 +1215,11 @@ - (void)updateMenuWhenDown { LiveUpdateMenuItemTitle(extraMenu, [extraMenu indexOfItem:pppMenuItem], [NSString stringWithFormat:kMenuDoubleIndentFormat, - [NSString stringWithFormat: - [localizedStrings objectForKey:kPPPConnectedWithTimeTitle], - hours, mins, secs]]); - } else { + [NSString stringWithFormat: + [localizedStrings objectForKey:kPPPConnectedWithTimeTitle], + hours, mins, secs]]); + } + else { LiveUpdateMenuItemTitle(extraMenu, [extraMenu indexOfItem:pppMenuItem], [NSString stringWithFormat:kMenuDoubleIndentFormat, kPPPConnectedTitle]); @@ -1159,7 +1231,7 @@ - (void)updateMenuWhenDown { LiveUpdateMenuItemTitle(extraMenu, [extraMenu indexOfItem:pppMenuItem], [NSString stringWithFormat:kMenuDoubleIndentFormat, - [localizedStrings objectForKey:kPPPDisconnectingTitle]]); + [localizedStrings objectForKey:kPPPDisconnectingTitle]]); }; } // Throughput updates @@ -1174,9 +1246,10 @@ - (void)updateMenuWhenDown { LiveUpdateMenuItemTitle(extraMenu, [extraMenu indexOfItem:targetItem], [NSString stringWithFormat:kMenuDoubleIndentFormat, - [NSString stringWithFormat:@"%@ %@", - [localizedStrings objectForKey:kTxLabel], - [self throughputStringForBytes:[throughputNumber doubleValue] inInterval:[sampleIntervalNum doubleValue]]]]); + [NSString stringWithFormat:@"%@ %@", + [localizedStrings objectForKey:kTxLabel], + [self throughputStringForBytes:[throughputNumber doubleValue] + inInterval:[sampleIntervalNum doubleValue]]]]); } targetItem = [updateInfoForService objectForKey:@"deltainitem"]; throughputNumber = [throughputDetails objectForKey:@"deltain"]; @@ -1184,9 +1257,10 @@ - (void)updateMenuWhenDown { LiveUpdateMenuItemTitle(extraMenu, [extraMenu indexOfItem:targetItem], [NSString stringWithFormat:kMenuDoubleIndentFormat, - [NSString stringWithFormat:@"%@ %@", - [localizedStrings objectForKey:kRxLabel], - [self throughputStringForBytes:[throughputNumber doubleValue] inInterval:[sampleIntervalNum doubleValue]]]]); + [NSString stringWithFormat:@"%@ %@", + [localizedStrings objectForKey:kRxLabel], + [self throughputStringForBytes:[throughputNumber doubleValue] + inInterval:[sampleIntervalNum doubleValue]]]]); } targetItem = [updateInfoForService objectForKey:@"totaloutitem"]; throughputNumber = [throughputDetails objectForKey:@"totalout"]; @@ -1194,7 +1268,8 @@ - (void)updateMenuWhenDown { LiveUpdateMenuItemTitle(extraMenu, [extraMenu indexOfItem:targetItem], [NSString stringWithFormat:kMenuDoubleIndentFormat, - [self trafficStringForNumber:throughputNumber withLabel:[localizedStrings objectForKey:kTxLabel]]]); + [self trafficStringForNumber:throughputNumber + withLabel:[localizedStrings objectForKey:kTxLabel]]]); } targetItem = [updateInfoForService objectForKey:@"totalinitem"]; throughputNumber = [throughputDetails objectForKey:@"totalin"]; @@ -1202,7 +1277,8 @@ - (void)updateMenuWhenDown { LiveUpdateMenuItemTitle(extraMenu, [extraMenu indexOfItem:targetItem], [NSString stringWithFormat:kMenuDoubleIndentFormat, - [self trafficStringForNumber:throughputNumber withLabel:[localizedStrings objectForKey:kRxLabel]]]); + [self trafficStringForNumber:throughputNumber + withLabel:[localizedStrings objectForKey:kRxLabel]]]); } targetItem = [updateInfoForService objectForKey:@"peakitem"]; throughputNumber = [throughputDetails objectForKey:@"peak"]; @@ -1210,7 +1286,7 @@ - (void)updateMenuWhenDown { LiveUpdateMenuItemTitle(extraMenu, [extraMenu indexOfItem:targetItem], [NSString stringWithFormat:kMenuDoubleIndentFormat, - [self throughputStringForBytesPerSecond:[throughputNumber doubleValue]]]); + [self throughputStringForBytesPerSecond:[throughputNumber doubleValue]]]); } } } @@ -1223,7 +1299,7 @@ - (void)updateMenuWhenDown { /////////////////////////////////////////////////////////////// // -// Menu actions +// Menu actions // /////////////////////////////////////////////////////////////// @@ -1250,28 +1326,31 @@ - (void)openInternetConnect:(id)sender { } } // openInternetConnect -- (void)resetTotals:(id)sender -{ - NSString *interfaceName = [sender representedObject]; - if (!interfaceName) return; - [netStats resetTotalsForInterfaceName:interfaceName]; + +- (void)resetTotals:(id)sender { + NSString *interfaceName = [sender representedObject]; + if (!interfaceName) + return; + [netStats resetTotalsForInterfaceName:interfaceName]; } + - (void)switchDisplay:(id)sender { NSString *interfaceName = [sender representedObject]; - if (!interfaceName) return; + if (!interfaceName) + return; // Sanity the name NSDictionary *newConfig = [netConfig interfaceConfigForInterfaceName:interfaceName]; - if (!newConfig) return; + if (!newConfig) + return; preferredInterfaceConfig = newConfig; // Update prefs [ourPrefs saveNetPreferInterface:interfaceName]; - [ourPrefs syncWithDisk]; // Send the notification to the pref pane [[NSNotificationCenter defaultCenter] postNotificationName:kPrefPaneBundleID - object:kPrefChangeNotification]; + object:kPrefChangeNotification]; } // switchDisplay @@ -1282,7 +1361,8 @@ - (void)copyAddress:(id)sender { owner:nil]; NSString *clipContent = [[sender representedObject] componentsJoinedByString:@", "]; [[NSPasteboard generalPasteboard] setString:clipContent forType:NSStringPboardType]; - } else { + } + else { NSLog(@"MenuMeterNet unable to copy IP addresses to clipboard."); } @@ -1293,10 +1373,11 @@ - (void)pppConnect:(id)sender { if ([sender representedObject]) { // SC connection SCNetworkConnectionRef connection = SCNetworkConnectionCreateWithServiceID( - kCFAllocatorDefault, - (CFStringRef)[sender representedObject], - NULL, - NULL); + kCFAllocatorDefault, + (CFStringRef)[sender representedObject], + NULL, + NULL); + // Undoc preference values CFArrayRef connectionOptionList = CFPreferencesCopyValue((CFStringRef)[sender representedObject], kAppleNetworkConnectDefaultsDomain, @@ -1305,12 +1386,15 @@ - (void)pppConnect:(id)sender { if (connection) { if (connectionOptionList && CFArrayGetCount(connectionOptionList)) { SCNetworkConnectionStart(connection, CFArrayGetValueAtIndex(connectionOptionList, 0), TRUE); - } else { + } + else { SCNetworkConnectionStart(connection, NULL, TRUE); } } - if (connection) CFRelease(connection); - if (connectionOptionList) CFRelease(connectionOptionList); + if (connection) + CFRelease(connection); + if (connectionOptionList) + CFRelease(connectionOptionList); } } // pppConnect @@ -1319,10 +1403,10 @@ - (void)pppDisconnect:(id)sender { if ([sender representedObject]) { SCNetworkConnectionRef connection = SCNetworkConnectionCreateWithServiceID( - kCFAllocatorDefault, - (CFStringRef)[sender representedObject], - NULL, - NULL); + kCFAllocatorDefault, + (CFStringRef)[sender representedObject], + NULL, + NULL); if (connection) { SCNetworkConnectionStop(connection, TRUE); CFRelease(connection); @@ -1333,102 +1417,102 @@ - (void)pppDisconnect:(id)sender { /////////////////////////////////////////////////////////////// // -// Pref routines +// Pref routines // /////////////////////////////////////////////////////////////// - (void)configFromPrefs:(NSNotification *)notification { #ifdef ELCAPITAN - [super configDisplay:kNetMenuBundleID fromPrefs:ourPrefs withTimerInterval:[ourPrefs netInterval]]; + [super configDisplay:kNetMenuBundleID + fromPrefs:ourPrefs + withTimerInterval:[ourPrefs netInterval]]; #endif - // Update prefs - [ourPrefs syncWithDisk]; - // Cache colors to skip archiver - txColor = [self colorByAdjustingForLightDark:[ourPrefs netTransmitColor]]; - rxColor = [self colorByAdjustingForLightDark:[ourPrefs netReceiveColor]]; - inactiveColor = [self colorByAdjustingForLightDark:[ourPrefs netInactiveColor]]; + txColor = [self colorByAdjustingForLightDark:[ourPrefs netTransmitColor]]; + rxColor = [self colorByAdjustingForLightDark:[ourPrefs netReceiveColor]]; + inactiveColor = [self colorByAdjustingForLightDark:[ourPrefs netInactiveColor]]; // Generate arrow bezier path offset as needed for current display mode - float arrowOffset = 0; - float viewHeight = self.height; + float arrowOffset = 0; + float viewHeight = self.height; if ([ourPrefs netDisplayMode] & kNetDisplayGraph) { arrowOffset = [ourPrefs netGraphLength] + kNetDisplayGapWidth; } - upArrow = [NSBezierPath bezierPath]; - [upArrow moveToPoint:NSMakePoint(arrowOffset + (kNetArrowDisplayWidth / 2) + 0.5f, viewHeight - 3.5f)]; - [upArrow lineToPoint:NSMakePoint(arrowOffset + 0.5f, viewHeight - 7.5f)]; - [upArrow lineToPoint:NSMakePoint(arrowOffset + 2.5f, viewHeight - 7.5f)]; - [upArrow lineToPoint:NSMakePoint(arrowOffset + 2.5f, viewHeight - 10.5f)]; - [upArrow lineToPoint:NSMakePoint(arrowOffset + kNetArrowDisplayWidth - 2.5f, viewHeight - 10.5f)]; - [upArrow lineToPoint:NSMakePoint(arrowOffset + kNetArrowDisplayWidth - 2.5f, viewHeight - 7.5f)]; - [upArrow lineToPoint:NSMakePoint(arrowOffset + kNetArrowDisplayWidth - 0.5f, viewHeight - 7.5f)]; - [upArrow closePath]; - [upArrow setLineWidth:0.6f]; - downArrow = [NSBezierPath bezierPath]; - [downArrow moveToPoint:NSMakePoint(arrowOffset + kNetArrowDisplayWidth / 2 + 0.5f, 2.5f)]; - [downArrow lineToPoint:NSMakePoint(arrowOffset + 0.5f, 6.5f)]; - [downArrow lineToPoint:NSMakePoint(arrowOffset + 2.5f, 6.5f)]; - [downArrow lineToPoint:NSMakePoint(arrowOffset + 2.5f, 9.5f)]; - [downArrow lineToPoint:NSMakePoint(arrowOffset + kNetArrowDisplayWidth - 2.5f, 9.5f)]; - [downArrow lineToPoint:NSMakePoint(arrowOffset + kNetArrowDisplayWidth - 2.5f, 6.5f)]; - [downArrow lineToPoint:NSMakePoint(arrowOffset + kNetArrowDisplayWidth - 0.5f, 6.5f)]; - [downArrow closePath]; - [downArrow setLineWidth:0.6f]; + NSBezierPath *arrow = [NSBezierPath bezierPath]; + [arrow moveToPoint:NSMakePoint(kNetArrowDisplayWidth / 2 + 0.5, tallMenuBar ? 0.5 : 2.5)]; + [arrow lineToPoint:NSMakePoint(0.5, tallMenuBar ? 5.5 : 6.5)]; + [arrow lineToPoint:NSMakePoint(2.5, tallMenuBar ? 5.5 : 6.5)]; + [arrow lineToPoint:NSMakePoint(2.5, tallMenuBar ? 9.5 : 9.5)]; + [arrow lineToPoint:NSMakePoint(kNetArrowDisplayWidth - 2.5, tallMenuBar ? 9.5 : 9.5)]; + [arrow lineToPoint:NSMakePoint(kNetArrowDisplayWidth - 2.5, tallMenuBar ? 5.5 : 6.5)]; + [arrow lineToPoint:NSMakePoint(kNetArrowDisplayWidth - 0.5, tallMenuBar ? 5.5 : 6.5)]; + [arrow closePath]; + [arrow setLineWidth:0.8]; + upArrow = [arrow copy]; + NSAffineTransform *transform = [NSAffineTransform new]; + [transform translateXBy:arrowOffset yBy:viewHeight]; + [transform scaleXBy:1 yBy:-1]; + [upArrow transformUsingAffineTransform:transform]; + downArrow = [arrow copy]; + transform = [NSAffineTransform new]; + [transform translateXBy:arrowOffset yBy:0]; + [downArrow transformUsingAffineTransform:transform]; // Prerender throughput labels + NSDictionary *attributes = @{NSFontAttributeName: throughputFont, + NSForegroundColorAttributeName: txColor}; NSAttributedString *renderTxString = [[NSAttributedString alloc] - initWithString:[localizedStrings objectForKey:kTxLabel] - attributes:[NSDictionary dictionaryWithObjectsAndKeys: - throughputFont, NSFontAttributeName, - txColor, NSForegroundColorAttributeName, - nil]]; + initWithString:[localizedStrings objectForKey:kTxLabel] + attributes:attributes]; + attributes = @{NSFontAttributeName: throughputFont, + NSForegroundColorAttributeName: rxColor}; NSAttributedString *renderRxString = [[NSAttributedString alloc] - initWithString:[localizedStrings objectForKey:kRxLabel] - attributes:[NSDictionary dictionaryWithObjectsAndKeys: - throughputFont, NSFontAttributeName, - rxColor, NSForegroundColorAttributeName, - nil]]; - if ([renderTxString size].width > [renderRxString size].width) { - throughputLabel = [[NSImage alloc] initWithSize:NSMakeSize([renderTxString size].width, viewHeight)]; - inactiveThroughputLabel = [[NSImage alloc] initWithSize:NSMakeSize([renderTxString size].width, viewHeight)]; - } else { - throughputLabel = [[NSImage alloc] initWithSize:NSMakeSize([renderRxString size].width, viewHeight)]; - inactiveThroughputLabel = [[NSImage alloc] initWithSize:NSMakeSize([renderRxString size].width, viewHeight)]; + initWithString:[localizedStrings objectForKey:kRxLabel] + attributes:attributes]; + + NSSize renderTxSize = renderTxString.size; + NSSize renderRxSize = renderRxString.size; + + NSSize throughputLabelSize; + if (renderTxSize.width > renderRxSize.width) { + throughputLabelSize = renderTxSize; } - [throughputLabel lockFocus]; - // No descenders, render lower + else { + throughputLabelSize = renderRxSize; + } + NSPoint renderRxPoint; + NSPoint renderTxPoint; if ([ourPrefs netDisplayOrientation] == kNetDisplayOrientRxTx) { - [renderRxString drawAtPoint:NSMakePoint(0, floorf(viewHeight / 2) - 2)]; - [renderTxString drawAtPoint:NSMakePoint(0, -1)]; - } else { - [renderTxString drawAtPoint:NSMakePoint(0, floorf(viewHeight / 2) - 2)]; - [renderRxString drawAtPoint:NSMakePoint(0, -1)]; + renderRxPoint = NSMakePoint(0, floor(viewHeight / 2) - 2); + renderTxPoint = NSMakePoint(0, -1); } - [throughputLabel unlockFocus]; + else { + renderTxPoint = NSMakePoint(0, floor(viewHeight / 2) - 2); + renderRxPoint = NSMakePoint(0, -1); + } + throughputLabel = [NSImage imageWithSize:throughputLabelSize + flipped:NO + drawingHandler:^BOOL(NSRect dstRect) { + [renderRxString drawAtPoint:renderRxPoint]; + [renderTxString drawAtPoint:renderTxPoint]; + return YES; + }]; + attributes = @{NSFontAttributeName: throughputFont, + NSForegroundColorAttributeName: inactiveColor}; renderTxString = [[NSAttributedString alloc] - initWithString:[localizedStrings objectForKey:kTxLabel] - attributes:[NSDictionary dictionaryWithObjectsAndKeys: - throughputFont, NSFontAttributeName, - inactiveColor, NSForegroundColorAttributeName, - nil]]; + initWithString:[localizedStrings objectForKey:kTxLabel] + attributes:attributes]; renderRxString = [[NSAttributedString alloc] - initWithString:[localizedStrings objectForKey:kRxLabel] - attributes:[NSDictionary dictionaryWithObjectsAndKeys: - throughputFont, NSFontAttributeName, - inactiveColor, NSForegroundColorAttributeName, - nil]]; - [inactiveThroughputLabel lockFocus]; - // No descenders, render lower - if ([ourPrefs netDisplayOrientation] == kNetDisplayOrientRxTx) { - [renderRxString drawAtPoint:NSMakePoint(0, floorf(viewHeight / 2) - 2)]; - [renderTxString drawAtPoint:NSMakePoint(0, -1)]; - } else { - [renderTxString drawAtPoint:NSMakePoint(0, floorf(viewHeight / 2) - 2)]; - [renderRxString drawAtPoint:NSMakePoint(0, -1)]; - } - [inactiveThroughputLabel unlockFocus]; + initWithString:[localizedStrings objectForKey:kRxLabel] + attributes:attributes]; + inactiveThroughputLabel = [NSImage imageWithSize:throughputLabelSize + flipped:NO + drawingHandler:^BOOL(NSRect dstRect) { + [renderRxString drawAtPoint:renderRxPoint]; + [renderTxString drawAtPoint:renderTxPoint]; + return YES; + }]; // Fix our menu view size to match our config menuWidth = 0; @@ -1443,89 +1527,65 @@ - (void)configFromPrefs:(NSNotification *)notification { } if ([ourPrefs netDisplayMode] & kNetDisplayThroughput) { displayCount++; - if ([ourPrefs netThroughputLabel]) menuWidth += (float)ceil([throughputLabel size].width); + if ([ourPrefs netThroughputLabel]) + menuWidth += (float)ceil([throughputLabel size].width); // Deal with localizable throughput suffix - float suffixMaxWidth = 0; - NSAttributedString *throughString = [[NSAttributedString alloc] - initWithString:[NSString stringWithFormat:@"999.9%@", - [localizedStrings objectForKey:[ourPrefs netThroughputBits] ? kBitPerSecondLabel : kBytePerSecondLabel]] - attributes:[NSDictionary dictionaryWithObjectsAndKeys: - throughputFont, NSFontAttributeName, - nil]]; - if ([throughString size].width > suffixMaxWidth) { - suffixMaxWidth = (float)[throughString size].width; + CGFloat suffixMaxWidth = 0; + + NSDictionary *attributes = @{NSFontAttributeName: throughputFont}; + NSSize numberSize = [@"999.9\u2009" sizeWithAttributes:attributes]; + + NSSize suffixSize; + suffixSize = [kBitPerSecondLabel sizeWithAttributes:attributes]; + if (suffixSize.width > suffixMaxWidth) { + suffixMaxWidth = suffixSize.width; } - throughString = [[NSAttributedString alloc] - initWithString:[NSString stringWithFormat:@"999.9%@", - [localizedStrings objectForKey:[ourPrefs netThroughputBits] ? kKbPerSecondLabel : kKBPerSecondLabel]] - attributes:[NSDictionary dictionaryWithObjectsAndKeys: - throughputFont, NSFontAttributeName, - nil]]; - if ([throughString size].width > suffixMaxWidth) { - suffixMaxWidth = (float)[throughString size].width; + suffixSize = [kKbPerSecondLabel sizeWithAttributes:attributes]; + if (suffixSize.width > suffixMaxWidth) { + suffixMaxWidth = suffixSize.width; } - throughString = [[NSAttributedString alloc] - initWithString:[NSString stringWithFormat:@"999.9%@", - [localizedStrings objectForKey:[ourPrefs netThroughputBits] ? kMbPerSecondLabel : kMBPerSecondLabel]] - attributes:[NSDictionary dictionaryWithObjectsAndKeys: - throughputFont, NSFontAttributeName, - nil]]; - if ([throughString size].width > suffixMaxWidth) { - suffixMaxWidth = (float)[throughString size].width; + suffixSize = [kMbPerSecondLabel sizeWithAttributes:attributes]; + if (suffixSize.width > suffixMaxWidth) { + suffixMaxWidth = suffixSize.width; } - throughString = [[NSAttributedString alloc] - initWithString:[NSString stringWithFormat:@"999.9%@", - [localizedStrings objectForKey:[ourPrefs netThroughputBits] ? kGbPerSecondLabel : kGBPerSecondLabel]] - attributes:[NSDictionary dictionaryWithObjectsAndKeys: - throughputFont, NSFontAttributeName, - nil]]; - if ([throughString size].width > suffixMaxWidth) { - suffixMaxWidth = (float)[throughString size].width; + suffixSize = [kGbPerSecondLabel sizeWithAttributes:attributes]; + if (suffixSize.width > suffixMaxWidth) { + suffixMaxWidth = suffixSize.width; } - menuWidth += ceilf(suffixMaxWidth); + suffixMaxWidth += numberSize.width; + + menuWidth += ceil(suffixMaxWidth); } // If more than one display is present we need to add a gaps if (displayCount) { - menuWidth += ((displayCount - 1) * kNetDisplayGapWidth); + menuWidth += (displayCount - 1) * kNetDisplayGapWidth; } // Force initial update - statusItem.button.image=self.image; + statusItem.button.image = self.image; } // configFromPrefs /////////////////////////////////////////////////////////////// // -// Data formatting +// Data formatting // /////////////////////////////////////////////////////////////// -- (NSString *)throughputStringForBytesPerSecond:(double)bps { - - return [self throughputStringForBytesPerSecond:bps withSpace:YES]; - -} // throughputStringForBytesPerSecond - - (NSString *)throughputStringForBytes:(double)bytes inInterval:(NSTimeInterval)interval { - if (interval <= 0) return nil; + if (interval <= 0) + return nil; return [self throughputStringForBytesPerSecond:bytes / interval]; } // throughputStringForBytes:inInterval: -- (NSString *)menubarThroughputStringForBytes:(double)bytes inInterval:(NSTimeInterval)interval { - - if (interval <= 0) return nil; - return [self throughputStringForBytesPerSecond:bytes / interval withSpace:NO]; - -} // menubarThroughputStringForBytes:inInterval: - -- (NSString *)throughputStringForBytesPerSecond:(double)bps withSpace:(Boolean)wantSpace { +- (NSString *)throughputStringForBytesPerSecond:(double)bps { NSArray *labels = @[kBytePerSecondLabel, kKBPerSecondLabel, kMBPerSecondLabel, kGBPerSecondLabel]; int kilo = kKiloBinary; if ([ourPrefs netThroughputBits]) { - labels = @[kBitPerSecondLabel, kKbPerSecondLabel, kMbPerSecondLabel, kGbPerSecondLabel]; + labels = @[kBitPerSecondLabel, kKbPerSecondLabel, kMbPerSecondLabel, kGbPerSecondLabel]; kilo = kKiloDecimal; bps *= 8; } @@ -1542,11 +1602,7 @@ - (NSString *)throughputStringForBytesPerSecond:(double)bps withSpace:(Boolean)w format = @"%.0f"; } - if (wantSpace) { - format = [NSString stringWithFormat:@"%@ %%@", format]; - } else { - format = [NSString stringWithFormat:@"%@%%@", format]; - } + format = [NSString stringWithFormat:@"%@\u2009%%@", format]; return [self stringifyNumber:bps withUnitLabel:unitLabel andFormat:format]; diff --git a/MenuExtras/MenuMeterNet/MenuMeterNetPPP.h b/MenuExtras/MenuMeterNet/MenuMeterNetPPP.h index 642de401..458f53cb 100644 --- a/MenuExtras/MenuMeterNet/MenuMeterNetPPP.h +++ b/MenuExtras/MenuMeterNet/MenuMeterNetPPP.h @@ -1,67 +1,71 @@ // // MenuMeterNetPPP.h // -// Talk to pppconfd +// Talk to pppconfd // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #import +#import #import #import -#import #import // PPP state machine from Apple PPPLib enum { - PPP_IDLE = 0, - PPP_INITIALIZE, - PPP_CONNECTLINK, - PPP_STATERESERVED, - PPP_ESTABLISH, - PPP_AUTHENTICATE, - PPP_CALLBACK, - PPP_NETWORK, - PPP_RUNNING, - PPP_TERMINATE, - PPP_DISCONNECTLINK, - PPP_HOLDOFF, - PPP_ONHOLD, - PPP_WAITONBUSY + PPP_IDLE = 0, + PPP_INITIALIZE, + PPP_CONNECTLINK, + PPP_STATERESERVED, + PPP_ESTABLISH, + PPP_AUTHENTICATE, + PPP_CALLBACK, + PPP_NETWORK, + PPP_RUNNING, + PPP_TERMINATE, + PPP_DISCONNECTLINK, + PPP_HOLDOFF, + PPP_ONHOLD, + PPP_WAITONBUSY }; - @interface MenuMeterNetPPP : NSObject { - int pppconfdSocket; - NSFileHandle *pppconfdHandle; + int pppconfdSocket; + NSFileHandle *pppconfdHandle; } // MenuMeterNetPPP // Singleton + + (id)sharedPPP; // PPP status + - (NSDictionary *)statusForInterfaceName:(NSString *)ifname; + - (NSDictionary *)statusForServiceID:(NSString *)serviceID; // PPP control + - (void)connectServiceID:(NSString *)serviceID; + - (void)disconnectServiceID:(NSString *)serviceID; @end diff --git a/MenuExtras/MenuMeterNet/MenuMeterNetPPP.m b/MenuExtras/MenuMeterNet/MenuMeterNetPPP.m index ffa4eb40..2ffa6faf 100644 --- a/MenuExtras/MenuMeterNet/MenuMeterNetPPP.m +++ b/MenuExtras/MenuMeterNet/MenuMeterNetPPP.m @@ -1,108 +1,108 @@ // // MenuMeterNetPPP.m // -// Talk to pppconfd +// Talk to pppconfd // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #import "MenuMeterNetPPP.h" - /////////////////////////////////////////////////////////////// // -// PPP interface from Apple PPPLib +// PPP interface from Apple PPPLib // /////////////////////////////////////////////////////////////// // PPP local socket path -#define kPPPSocketPath "/var/run/pppconfd\0" +#define kPPPSocketPath "/var/run/pppconfd\0" // Typedef for PPP messages, from Apple PPPLib struct ppp_msg_hdr { - u_int16_t m_flags; // special flags - u_int16_t m_type; // type of the message - u_int32_t m_result; // error code of notification message - u_int32_t m_cookie; // user param - u_int32_t m_link; // link for this message - u_int32_t m_len; // len of the following data + u_int16_t m_flags; // special flags + u_int16_t m_type; // type of the message + u_int32_t m_result; // error code of notification message + u_int32_t m_cookie; // user param + u_int32_t m_link; // link for this message + u_int32_t m_len; // len of the following data }; // PPP command codes, also from Apple PPPLib enum { - PPP_VERSION = 1, - PPP_STATUS, - PPP_CONNECT, - PPP_DISCONNECT = 5, - PPP_GETOPTION, - PPP_SETOPTION, - PPP_ENABLE_EVENT, - PPP_DISABLE_EVENT, - PPP_EVENT, - PPP_GETNBLINKS, - PPP_GETLINKBYINDEX, - PPP_GETLINKBYSERVICEID, - PPP_GETLINKBYIFNAME, - PPP_SUSPEND, - PPP_RESUME + PPP_VERSION = 1, + PPP_STATUS, + PPP_CONNECT, + PPP_DISCONNECT = 5, + PPP_GETOPTION, + PPP_SETOPTION, + PPP_ENABLE_EVENT, + PPP_DISABLE_EVENT, + PPP_EVENT, + PPP_GETNBLINKS, + PPP_GETLINKBYINDEX, + PPP_GETLINKBYSERVICEID, + PPP_GETLINKBYIFNAME, + PPP_SUSPEND, + PPP_RESUME }; // And the PPP status struct struct ppp_status { - // connection stats - u_int32_t status; - union { - struct connected { - u_int32_t timeElapsed; - u_int32_t timeRemaining; - // bytes stats - u_int32_t inBytes; - u_int32_t inPackets; - u_int32_t inErrors; - u_int32_t outBytes; - u_int32_t outPackets; - u_int32_t outErrors; - } run; - struct disconnected { - u_int32_t lastDiscCause; - } disc; - struct waitonbusy { - u_int32_t timeRemaining; - } busy; - } s; + // connection stats + u_int32_t status; + union { + struct connected { + u_int32_t timeElapsed; + u_int32_t timeRemaining; + // bytes stats + u_int32_t inBytes; + u_int32_t inPackets; + u_int32_t inErrors; + u_int32_t outBytes; + u_int32_t outPackets; + u_int32_t outErrors; + } run; + struct disconnected { + u_int32_t lastDiscCause; + } disc; + struct waitonbusy { + u_int32_t timeRemaining; + } busy; + } s; }; /////////////////////////////////////////////////////////////// // -// Private methods +// Private methods // /////////////////////////////////////////////////////////////// @interface MenuMeterNetPPP (PrivateMethods) - (uint32_t)pppconfdLinkCount; + - (NSData *)pppconfdExecMessage:(NSData *)message; @end /////////////////////////////////////////////////////////////// // -// Singleton +// Singleton // /////////////////////////////////////////////////////////////// @@ -125,11 +125,11 @@ + (id)sharedPPP { /////////////////////////////////////////////////////////////// // -// init/dealloc +// init/dealloc // /////////////////////////////////////////////////////////////// -- (id)init { +- (instancetype)init { self = [super init]; if (!self) { @@ -138,7 +138,7 @@ - (id)init { // Establish or connection to the PPP socket pppconfdSocket = socket(AF_LOCAL, SOCK_STREAM, 0); - struct sockaddr_un socketaddr = { 0, AF_LOCAL, kPPPSocketPath }; + struct sockaddr_un socketaddr = {0, AF_LOCAL, kPPPSocketPath}; if (connect(pppconfdSocket, (struct sockaddr *)&socketaddr, (socklen_t)sizeof(socketaddr))) { NSLog(@"MenuMeterNetPPP unable to establish socket for pppconfd. Abort."); return nil; @@ -164,7 +164,7 @@ - (void)dealloc { /////////////////////////////////////////////////////////////// // -// PPP status +// PPP status // /////////////////////////////////////////////////////////////// @@ -173,92 +173,101 @@ - (NSDictionary *)statusForInterfaceName:(NSString *)ifname { // Name in UTF-8 NSData *ifnameData = [ifname dataUsingEncoding:NSUTF8StringEncoding]; #ifdef __LP64__ - if ([ifnameData length] > UINT_MAX) return nil; + if ([ifnameData length] > UINT_MAX) + return nil; #endif // Get the link id for the interface - struct ppp_msg_hdr idMsg = { 0, PPP_GETLINKBYIFNAME, 0, 0, -1, (u_int32_t)[ifnameData length] }; + struct ppp_msg_hdr idMsg = {0, PPP_GETLINKBYIFNAME, 0, 0, -1, (u_int32_t)[ifnameData length]}; NSMutableData *idMsgData = [NSMutableData dataWithBytes:&idMsg length:sizeof(idMsg)]; [idMsgData appendData:ifnameData]; NSData *idReply = [self pppconfdExecMessage:idMsgData]; uint32_t linkID = 0; - if ([idReply length] != sizeof(uint32_t)) return nil; + if ([idReply length] != sizeof(uint32_t)) + return nil; [idReply getBytes:&linkID]; // Now get status of that link - struct ppp_msg_hdr statusMsg = { 0, PPP_STATUS, 0, 0, linkID, 0 }; + struct ppp_msg_hdr statusMsg = {0, PPP_STATUS, 0, 0, linkID, 0}; NSData *statusReply = [self pppconfdExecMessage:[NSData dataWithBytes:&statusMsg length:sizeof(statusMsg)]]; - if ([statusReply length] != sizeof(struct ppp_status)) return nil; + if ([statusReply length] != sizeof(struct ppp_status)) + return nil; struct ppp_status *pppStatus = (struct ppp_status *)[statusReply bytes]; if (pppStatus->status == PPP_RUNNING) { return [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithUnsignedInt:pppStatus->status], - @"status", - [NSNumber numberWithUnsignedInt:pppStatus->s.run.inBytes], - @"inBytes", - [NSNumber numberWithUnsignedInt:pppStatus->s.run.outBytes], - @"outBytes", - [NSNumber numberWithUnsignedInt:pppStatus->s.run.timeElapsed], - @"timeElapsed", - [NSNumber numberWithUnsignedInt:pppStatus->s.run.timeRemaining], - @"timeRemaining", - nil]; - } else { + [NSNumber numberWithUnsignedInt:pppStatus->status], + @"status", + [NSNumber numberWithUnsignedInt:pppStatus->s.run.inBytes], + @"inBytes", + [NSNumber numberWithUnsignedInt:pppStatus->s.run.outBytes], + @"outBytes", + [NSNumber numberWithUnsignedInt:pppStatus->s.run.timeElapsed], + @"timeElapsed", + [NSNumber numberWithUnsignedInt:pppStatus->s.run.timeRemaining], + @"timeRemaining", + nil]; + } + else { return [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithUnsignedInt:pppStatus->status], - @"status", - nil]; + [NSNumber numberWithUnsignedInt:pppStatus->status], + @"status", + nil]; } } // statusForInterfaceName -- (NSDictionary *)statusForServiceID:(NSString *)serviceID; { +- (NSDictionary *)statusForServiceID:(NSString *)serviceID; +{ // Service in UTF-8 NSData *serviceIDData = [serviceID dataUsingEncoding:NSUTF8StringEncoding]; #ifdef __LP64__ - if ([serviceIDData length] > UINT_MAX) return nil; + if ([serviceIDData length] > UINT_MAX) + return nil; #endif // We get the link id for the service - struct ppp_msg_hdr idMsg = { 0, PPP_GETLINKBYSERVICEID, 0, 0, -1, (u_int32_t)[serviceIDData length] }; + struct ppp_msg_hdr idMsg = {0, PPP_GETLINKBYSERVICEID, 0, 0, -1, (u_int32_t)[serviceIDData length]}; NSMutableData *idMsgData = [NSMutableData dataWithBytes:&idMsg length:sizeof(idMsg)]; [idMsgData appendData:serviceIDData]; NSData *idReply = [self pppconfdExecMessage:idMsgData]; uint32_t linkID = 0; - if ([idReply length] != sizeof(uint32_t)) return nil; + if ([idReply length] != sizeof(uint32_t)) + return nil; [idReply getBytes:&linkID]; // Now get status of that link - struct ppp_msg_hdr statusMsg = { 0, PPP_STATUS, 0, 0, linkID, 0 }; + struct ppp_msg_hdr statusMsg = {0, PPP_STATUS, 0, 0, linkID, 0}; NSData *statusReply = [self pppconfdExecMessage:[NSData dataWithBytes:&statusMsg length:sizeof(statusMsg)]]; - if ([statusReply length] != sizeof(struct ppp_status)) return nil; + if ([statusReply length] != sizeof(struct ppp_status)) + return nil; struct ppp_status *pppStatus = (struct ppp_status *)[statusReply bytes]; if (pppStatus->status == PPP_RUNNING) { return [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithUnsignedInt:pppStatus->status], - @"status", - [NSNumber numberWithUnsignedInt:pppStatus->s.run.inBytes], - @"inBytes", - [NSNumber numberWithUnsignedInt:pppStatus->s.run.outBytes], - @"outBytes", - [NSNumber numberWithUnsignedInt:pppStatus->s.run.timeElapsed], - @"timeElapsed", - [NSNumber numberWithUnsignedInt:pppStatus->s.run.timeRemaining], - @"timeRemaining", - nil]; - } else { + [NSNumber numberWithUnsignedInt:pppStatus->status], + @"status", + [NSNumber numberWithUnsignedInt:pppStatus->s.run.inBytes], + @"inBytes", + [NSNumber numberWithUnsignedInt:pppStatus->s.run.outBytes], + @"outBytes", + [NSNumber numberWithUnsignedInt:pppStatus->s.run.timeElapsed], + @"timeElapsed", + [NSNumber numberWithUnsignedInt:pppStatus->s.run.timeRemaining], + @"timeRemaining", + nil]; + } + else { return [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithUnsignedInt:pppStatus->status], - @"status", - nil]; + [NSNumber numberWithUnsignedInt:pppStatus->status], + @"status", + nil]; } } // statusForServiceID /////////////////////////////////////////////////////////////// // -// PPP control +// PPP control // /////////////////////////////////////////////////////////////// @@ -267,20 +276,22 @@ - (void)connectServiceID:(NSString *)serviceID { // Service in UTF-8 NSData *serviceIDData = [serviceID dataUsingEncoding:NSUTF8StringEncoding]; #ifdef __LP64__ - if ([serviceIDData length] > UINT_MAX) return; + if ([serviceIDData length] > UINT_MAX) + return; #endif // We get the link id for the service - struct ppp_msg_hdr idMsg = { 0, PPP_GETLINKBYSERVICEID, 0, 0, -1, (u_int32_t)[serviceIDData length] }; + struct ppp_msg_hdr idMsg = {0, PPP_GETLINKBYSERVICEID, 0, 0, -1, (u_int32_t)[serviceIDData length]}; NSMutableData *idMsgData = [NSMutableData dataWithBytes:&idMsg length:sizeof(idMsg)]; [idMsgData appendData:serviceIDData]; NSData *idReply = [self pppconfdExecMessage:idMsgData]; uint32_t linkID = 0; - if ([idReply length] != sizeof(uint32_t)) return; + if ([idReply length] != sizeof(uint32_t)) + return; [idReply getBytes:&linkID]; // Connect the link - struct ppp_msg_hdr connectMsg = { 0, PPP_CONNECT, 0, 0, linkID, 0 }; + struct ppp_msg_hdr connectMsg = {0, PPP_CONNECT, 0, 0, linkID, 0}; [self pppconfdExecMessage:[NSData dataWithBytes:&connectMsg length:sizeof(connectMsg)]]; } // connectServiceID @@ -290,34 +301,36 @@ - (void)disconnectServiceID:(NSString *)serviceID { // Service in UTF-8 NSData *serviceIDData = [serviceID dataUsingEncoding:NSUTF8StringEncoding]; #ifdef __LP64__ - if ([serviceIDData length] > UINT_MAX) return; + if ([serviceIDData length] > UINT_MAX) + return; #endif // We get the link id for the service - struct ppp_msg_hdr idMsg = { 0, PPP_GETLINKBYSERVICEID, 0, 0, -1, (u_int32_t)[serviceIDData length] }; + struct ppp_msg_hdr idMsg = {0, PPP_GETLINKBYSERVICEID, 0, 0, -1, (u_int32_t)[serviceIDData length]}; NSMutableData *idMsgData = [NSMutableData dataWithBytes:&idMsg length:sizeof(idMsg)]; [idMsgData appendData:serviceIDData]; NSData *idReply = [self pppconfdExecMessage:idMsgData]; uint32_t linkID = 0; - if ([idReply length] != sizeof(uint32_t)) return; + if ([idReply length] != sizeof(uint32_t)) + return; [idReply getBytes:&linkID]; // Disconnect the link - struct ppp_msg_hdr disconnectMsg = { 0, PPP_DISCONNECT, 0, 0, linkID, 0 }; + struct ppp_msg_hdr disconnectMsg = {0, PPP_DISCONNECT, 0, 0, linkID, 0}; [self pppconfdExecMessage:[NSData dataWithBytes:&disconnectMsg length:sizeof(disconnectMsg)]]; } // disconnectServiceID /////////////////////////////////////////////////////////////// // -// Private Methods +// Private Methods // /////////////////////////////////////////////////////////////// - (uint32_t)pppconfdLinkCount { // Message block and reply - struct ppp_msg_hdr numlinkmsg = { 0, PPP_GETNBLINKS, 0, 0, -1, 0 }; + struct ppp_msg_hdr numlinkmsg = {0, PPP_GETNBLINKS, 0, 0, -1, 0}; NSData *reply = [self pppconfdExecMessage:[NSData dataWithBytes:&numlinkmsg length:sizeof(numlinkmsg)]]; // Size the reply if ([reply length] == sizeof(uint32_t)) { diff --git a/MenuExtras/MenuMeterNet/MenuMeterNetStats.h b/MenuExtras/MenuMeterNet/MenuMeterNetStats.h index aebb4c2b..be554ff3 100644 --- a/MenuExtras/MenuMeterNet/MenuMeterNetStats.h +++ b/MenuExtras/MenuMeterNet/MenuMeterNetStats.h @@ -1,50 +1,52 @@ // // MenuMeterNetStats.h // -// Reader object for network throughput info +// Reader object for network throughput info // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // +#import "MenuMeterNetPPP.h" #import -#import -#import -#import +#import #import #import #import #import -#import -#import "MenuMeterNetPPP.h" +#import +#import +#import @interface MenuMeterNetStats : NSObject { // Old data for containing prior reads - NSMutableDictionary *lastData; + NSMutableDictionary *lastData; // Buffer we keep around - size_t sysctlBufferSize; - uint8_t *sysctlBuffer; + size_t sysctlBufferSize; + uint8_t *sysctlBuffer; // PPP data - MenuMeterNetPPP *pppGatherer; + MenuMeterNetPPP *pppGatherer; } // MenuMeterNetStats // Net usage info + - (NSDictionary *)netStatsForInterval:(NSTimeInterval)sampleInterval; -- (void)resetTotalsForInterfaceName:(NSString*)interfaceName; + +- (void)resetTotalsForInterfaceName:(NSString *)interfaceName; @end diff --git a/MenuExtras/MenuMeterNet/MenuMeterNetStats.m b/MenuExtras/MenuMeterNet/MenuMeterNetStats.m index 9c8b57f7..8959f2b9 100644 --- a/MenuExtras/MenuMeterNet/MenuMeterNetStats.m +++ b/MenuExtras/MenuMeterNet/MenuMeterNetStats.m @@ -1,24 +1,24 @@ // // MenuMeterNetStats.m // -// Reader object for network throughput info +// Reader object for network throughput info // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #import "MenuMeterNetStats.h" @@ -27,11 +27,11 @@ @implementation MenuMeterNetStats /////////////////////////////////////////////////////////////// // -// init/dealloc +// init/dealloc // /////////////////////////////////////////////////////////////// -- (id)init { +- (instancetype)init { self = [super init]; if (!self) { @@ -46,7 +46,7 @@ - (id)init { } // Prefetch the data first time - [self netStatsForInterval:1.0f]; + [self netStatsForInterval:1.0]; return self; @@ -55,50 +55,56 @@ - (id)init { - (void)dealloc { // Free our sysctl buffer - if (sysctlBuffer) free(sysctlBuffer); + if (sysctlBuffer) + free(sysctlBuffer); } // dealloc /////////////////////////////////////////////////////////////// // -// Net usage info, based mostly on code found in -// XResourceGraph which got it in turn from gkrellm. -// It reads data from the routing tables using sysctl, -// which, unlike the kernel memory reads used in netstat -// and top, does not require root access +// Net usage info, based mostly on code found in +// XResourceGraph which got it in turn from gkrellm. +// It reads data from the routing tables using sysctl, +// which, unlike the kernel memory reads used in netstat +// and top, does not require root access // /////////////////////////////////////////////////////////////// -- (void)resetTotalsForInterfaceName:(NSString*)interfaceName -{ - NSDictionary *oldStats = [lastData objectForKey:interfaceName]; - if(oldStats){ - NSMutableDictionary*x=[oldStats mutableCopy]; - x[@"totalin"]=@(0); - x[@"totalout"]=@(0); - lastData[interfaceName]=x; - } + +- (void)resetTotalsForInterfaceName:(NSString *)interfaceName { + NSDictionary *oldStats = [lastData objectForKey:interfaceName]; + if (oldStats) { + NSMutableDictionary *x = [oldStats mutableCopy]; + x[@"totalin"] = @(0); + x[@"totalout"] = @(0); + lastData[interfaceName] = x; + } } + - (NSDictionary *)netStatsForInterval:(NSTimeInterval)sampleInterval { // Get sizing info from sysctl and resize as needed. - int mib[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 }; + int mib[] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0}; size_t currentSize = 0; - if (sysctl(mib, 6, NULL, ¤tSize, NULL, 0) != 0) return nil; + if (sysctl(mib, 6, NULL, ¤tSize, NULL, 0) != 0) + return nil; if (!sysctlBuffer || (currentSize > sysctlBufferSize)) { - if (sysctlBuffer) free(sysctlBuffer); + if (sysctlBuffer) + free(sysctlBuffer); sysctlBufferSize = 0; sysctlBuffer = malloc(currentSize); - if (!sysctlBuffer) return nil; + if (!sysctlBuffer) + return nil; sysctlBufferSize = currentSize; } // Read in new data - if (sysctl(mib, 6, sysctlBuffer, ¤tSize, NULL, 0) != 0) return nil; + if (sysctl(mib, 6, sysctlBuffer, ¤tSize, NULL, 0) != 0) + return nil; // Walk through the reply uint8_t *currentData = sysctlBuffer; uint8_t *currentDataEnd = sysctlBuffer + currentSize; - NSMutableDictionary *newStats = [NSMutableDictionary dictionary]; + NSMutableDictionary *newStats = [NSMutableDictionary dictionary]; while (currentData < currentDataEnd) { // Expecting interface data struct if_msghdr *ifmsg = (struct if_msghdr *)currentData; @@ -146,12 +152,14 @@ - (NSDictionary *)netStatsForInterval:(NSTimeInterval)sampleInterval { uint64_t totalIn = 0, totalOut = 0; if (lastifIn > ifIn) { totalIn = lastTotalIn + ifIn + UINT_MAX - lastifIn + 1; - } else { + } + else { totalIn = lastTotalIn + (ifIn - lastifIn); } if (lastifOut > ifOut) { totalOut = lastTotalOut + ifOut + UINT_MAX - lastifOut + 1; - } else { + } + else { totalOut = lastTotalOut + (ifOut - lastifOut); } // New deltas (64-bit overflow guard) @@ -160,45 +168,49 @@ - (NSDictionary *)netStatsForInterval:(NSTimeInterval)sampleInterval { // Peak double peak = [[oldStats objectForKey:@"peak"] doubleValue]; if (sampleInterval > 0) { - if (peak < (deltaIn / sampleInterval)) peak = deltaIn / sampleInterval; - if (peak < (deltaOut / sampleInterval)) peak = deltaOut / sampleInterval; + if (peak < (deltaIn / sampleInterval)) + peak = deltaIn / sampleInterval; + if (peak < (deltaOut / sampleInterval)) + peak = deltaOut / sampleInterval; } [newStats setObject:[NSDictionary dictionaryWithObjectsAndKeys: - [pppStats objectForKey:@"inBytes"], - @"ifin", - [pppStats objectForKey:@"outBytes"], - @"ifout", - [NSNumber numberWithUnsignedLongLong:deltaIn], - @"deltain", - [NSNumber numberWithUnsignedLongLong:deltaOut], - @"deltaout", - [NSNumber numberWithUnsignedLongLong:totalIn], - @"totalin", - [NSNumber numberWithUnsignedLongLong:totalOut], - @"totalout", - [NSNumber numberWithDouble:peak], - @"peak", - nil] - forKey:interfaceName]; - } else { + [pppStats objectForKey:@"inBytes"], + @"ifin", + [pppStats objectForKey:@"outBytes"], + @"ifout", + [NSNumber numberWithUnsignedLongLong:deltaIn], + @"deltain", + [NSNumber numberWithUnsignedLongLong:deltaOut], + @"deltaout", + [NSNumber numberWithUnsignedLongLong:totalIn], + @"totalin", + [NSNumber numberWithUnsignedLongLong:totalOut], + @"totalout", + [NSNumber numberWithDouble:peak], + @"peak", + nil] + forKey:interfaceName]; + } + else { [newStats setObject:[NSDictionary dictionaryWithObjectsAndKeys: - [pppStats objectForKey:@"inBytes"], - @"totalin", - [pppStats objectForKey:@"outBytes"], - @"totalout", - [pppStats objectForKey:@"inBytes"], - @"ifin", - [pppStats objectForKey:@"outBytes"], - @"ifout", - // No deltas since that would make - // first sample artificially large - [NSNumber numberWithDouble:0.0], - @"peak", - nil] + [pppStats objectForKey:@"inBytes"], + @"totalin", + [pppStats objectForKey:@"outBytes"], + @"totalout", + [pppStats objectForKey:@"inBytes"], + @"ifin", + [pppStats objectForKey:@"outBytes"], + @"ifout", + // No deltas since that would make + // first sample artificially large + [NSNumber numberWithDouble:0.0], + @"peak", + nil] forKey:interfaceName]; } } - } else { + } + else { // Not a PPP connection if (oldStats && (ifmsg->ifm_flags & IFF_UP)) { // Non-PPP data is sized at u_long, which means we need to deal @@ -212,12 +224,14 @@ - (NSDictionary *)netStatsForInterval:(NSTimeInterval)sampleInterval { uint32_t lastifOut = [[oldStats objectForKey:@"ifout"] unsignedIntValue]; if (lastifIn > ifmsg->ifm_data.ifi_ibytes) { totalIn = lastTotalIn + ifmsg->ifm_data.ifi_ibytes + UINT_MAX - lastifIn + 1; - } else { + } + else { totalIn = lastTotalIn + (ifmsg->ifm_data.ifi_ibytes - lastifIn); } if (lastifOut > ifmsg->ifm_data.ifi_obytes) { totalOut = lastTotalOut + ifmsg->ifm_data.ifi_obytes + UINT_MAX - lastifOut + 1; - } else { + } + else { totalOut = lastTotalOut + (ifmsg->ifm_data.ifi_obytes - lastifOut); } // New deltas (64-bit overflow guard, full paranoia) @@ -226,41 +240,44 @@ - (NSDictionary *)netStatsForInterval:(NSTimeInterval)sampleInterval { // Peak double peak = [[oldStats objectForKey:@"peak"] doubleValue]; if (sampleInterval > 0) { - if (peak < (deltaIn / sampleInterval)) peak = deltaIn / sampleInterval; - if (peak < (deltaOut / sampleInterval)) peak = deltaOut / sampleInterval; + if (peak < (deltaIn / sampleInterval)) + peak = deltaIn / sampleInterval; + if (peak < (deltaOut / sampleInterval)) + peak = deltaOut / sampleInterval; } [newStats setObject:[NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithUnsignedInt:ifmsg->ifm_data.ifi_ibytes], - @"ifin", - [NSNumber numberWithUnsignedInt:ifmsg->ifm_data.ifi_obytes], - @"ifout", - [NSNumber numberWithUnsignedLongLong:deltaIn], - @"deltain", - [NSNumber numberWithUnsignedLongLong:deltaOut], - @"deltaout", - [NSNumber numberWithUnsignedLongLong:totalIn], - @"totalin", - [NSNumber numberWithUnsignedLongLong:totalOut], - @"totalout", - [NSNumber numberWithDouble:peak], - @"peak", - nil] - forKey:interfaceName]; - } else { + [NSNumber numberWithUnsignedInt:ifmsg->ifm_data.ifi_ibytes], + @"ifin", + [NSNumber numberWithUnsignedInt:ifmsg->ifm_data.ifi_obytes], + @"ifout", + [NSNumber numberWithUnsignedLongLong:deltaIn], + @"deltain", + [NSNumber numberWithUnsignedLongLong:deltaOut], + @"deltaout", + [NSNumber numberWithUnsignedLongLong:totalIn], + @"totalin", + [NSNumber numberWithUnsignedLongLong:totalOut], + @"totalout", + [NSNumber numberWithDouble:peak], + @"peak", + nil] + forKey:interfaceName]; + } + else { [newStats setObject:[NSDictionary dictionaryWithObjectsAndKeys: - // Paranoia, is this where the neg numbers came from? - [NSNumber numberWithUnsignedInt:ifmsg->ifm_data.ifi_ibytes], - @"ifin", - [NSNumber numberWithUnsignedInt:ifmsg->ifm_data.ifi_obytes], - @"ifout", - [NSNumber numberWithUnsignedLongLong:ifmsg->ifm_data.ifi_ibytes], - @"totalin", - [NSNumber numberWithUnsignedLongLong:ifmsg->ifm_data.ifi_obytes], - @"totalout", - [NSNumber numberWithDouble:0], - @"peak", - nil] - forKey:interfaceName]; + // Paranoia, is this where the neg numbers came from? + [NSNumber numberWithUnsignedInt:ifmsg->ifm_data.ifi_ibytes], + @"ifin", + [NSNumber numberWithUnsignedInt:ifmsg->ifm_data.ifi_obytes], + @"ifout", + [NSNumber numberWithUnsignedLongLong:ifmsg->ifm_data.ifi_ibytes], + @"totalin", + [NSNumber numberWithUnsignedLongLong:ifmsg->ifm_data.ifi_obytes], + @"totalout", + [NSNumber numberWithDouble:0], + @"peak", + nil] + forKey:interfaceName]; } } diff --git a/MenuMeters.pch b/MenuMeters.pch index 8ba47ea2..a2c5eac0 100644 --- a/MenuMeters.pch +++ b/MenuMeters.pch @@ -1,24 +1,24 @@ // -// MenuMeters.pch +// MenuMeters.pch // -// Prefix header for MenuMeters +// Prefix header for MenuMeters // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifdef __OBJC__ @@ -32,3 +32,9 @@ #import #import #import + +#ifdef DEBUG +#define MMLog(args...) (void)printf("%i %s: %s\n", __LINE__, __PRETTY_FUNCTION__, [[NSString stringWithFormat:args] UTF8String]) +#else +#define MMLog(args...) // stubbed out +#endif diff --git a/MenuMeters.xcodeproj/project.pbxproj b/MenuMeters.xcodeproj/project.pbxproj index 30450fc8..a68982c2 100644 --- a/MenuMeters.xcodeproj/project.pbxproj +++ b/MenuMeters.xcodeproj/project.pbxproj @@ -79,6 +79,8 @@ 33B440112594675E00CBBEDF /* com.ragingmenace.MenuMeters.plist in Resources */ = {isa = PBXBuildFile; fileRef = 33B440102594675E00CBBEDF /* com.ragingmenace.MenuMeters.plist */; }; 33B440122594675E00CBBEDF /* com.ragingmenace.MenuMeters.plist in Resources */ = {isa = PBXBuildFile; fileRef = 33B440102594675E00CBBEDF /* com.ragingmenace.MenuMeters.plist */; }; 33F0921923673DAC00953CAB /* releases.html in Resources */ = {isa = PBXBuildFile; fileRef = 33F0921823673DAC00953CAB /* releases.html */; }; + 56834990272F332C0024B69D /* MenuMeterCPU.m in Sources */ = {isa = PBXBuildFile; fileRef = 5683498F272F332C0024B69D /* MenuMeterCPU.m */; }; + 56834991272F332C0024B69D /* MenuMeterCPU.m in Sources */ = {isa = PBXBuildFile; fileRef = 5683498F272F332C0024B69D /* MenuMeterCPU.m */; }; 6349C10924BB733300C6FC99 /* EMCLoginItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 908780A91FB087D70053DDC5 /* EMCLoginItem.m */; }; 6349C10A24BB733300C6FC99 /* MenuMeterDiskExtra.m in Sources */ = {isa = PBXBuildFile; fileRef = D42EC95D03D49AE400A87BC9 /* MenuMeterDiskExtra.m */; }; 6349C10B24BB733300C6FC99 /* MenuMeterWorkarounds.m in Sources */ = {isa = PBXBuildFile; fileRef = D48A79F41018B051008E3207 /* MenuMeterWorkarounds.m */; }; @@ -196,6 +198,7 @@ 538B152824465532008BAFC2 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/MenuMetersPref.strings; sourceTree = ""; }; 538B152924465532008BAFC2 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/DiskImageSet.strings; sourceTree = ""; }; 538B152A24465532008BAFC2 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/Localizable.strings; sourceTree = ""; }; + 5683498F272F332C0024B69D /* MenuMeterCPU.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = MenuMeterCPU.m; path = Common/MenuMeterCPU.m; sourceTree = ""; }; 6349C15124BB733300C6FC99 /* MenuMeters.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MenuMeters.app; sourceTree = BUILT_PRODUCTS_DIR; }; 9023745A1E91612100B096A8 /* InfoPlistPreprocessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InfoPlistPreprocessor.h; sourceTree = ""; }; 908780A71FB087B90053DDC5 /* EMCLoginItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EMCLoginItem.h; sourceTree = ""; }; @@ -395,6 +398,7 @@ 3345DD2E1B6BEFDE003843FC /* MenuMetersMenuExtraBase.m */, D4510D9104F2F0FD00A87BC9 /* MenuMeters.h */, D40DB4C403D260E800A87BC9 /* MenuMeterCPU.h */, + 5683498F272F332C0024B69D /* MenuMeterCPU.m */, D40DB4C503D260E800A87BC9 /* MenuMeterDisk.h */, D40DB4C203D260E800A87BC9 /* MenuMeterMem.h */, D40DB4C603D260E800A87BC9 /* MenuMeterNet.h */, @@ -834,6 +838,7 @@ 33883CFA23655C9900B8AC14 /* smc_reader.m in Sources */, 33883CFB23655C9900B8AC14 /* MenuMeterCPUTopProcesses.m in Sources */, 33883CFC23655C9900B8AC14 /* MenuMeterMemStats.m in Sources */, + 56834990272F332C0024B69D /* MenuMeterCPU.m in Sources */, 33883CFD23655C9900B8AC14 /* MenuMeterDiskSpace.m in Sources */, 33883CFE23655C9900B8AC14 /* MenuMeterDiskIO.m in Sources */, 33883D3423655CBF00B8AC14 /* MenuMetersPref.m in Sources */, @@ -866,6 +871,7 @@ 6349C11424BB733300C6FC99 /* smc_reader.m in Sources */, 6349C11524BB733300C6FC99 /* MenuMeterCPUTopProcesses.m in Sources */, 6349C11624BB733300C6FC99 /* MenuMeterMemStats.m in Sources */, + 56834991272F332C0024B69D /* MenuMeterCPU.m in Sources */, 6349C11724BB733300C6FC99 /* MenuMeterDiskSpace.m in Sources */, 6349C11824BB733300C6FC99 /* MenuMeterDiskIO.m in Sources */, 6349C11924BB733300C6FC99 /* MenuMetersPref.m in Sources */, diff --git a/MenuMetersApp/AppDelegate.h b/MenuMetersApp/AppDelegate.h index 3600a1e1..43cad077 100644 --- a/MenuMetersApp/AppDelegate.h +++ b/MenuMetersApp/AppDelegate.h @@ -10,6 +10,4 @@ @interface AppDelegate : NSObject - @end - diff --git a/MenuMetersApp/AppDelegate.m b/MenuMetersApp/AppDelegate.m index 81596f22..16fa1049 100644 --- a/MenuMetersApp/AppDelegate.m +++ b/MenuMetersApp/AppDelegate.m @@ -21,115 +21,111 @@ @interface AppDelegate () @property (weak) IBOutlet NSWindow *window; @end -@implementation AppDelegate -{ - MenuMeterCPUExtra*cpuExtra; - MenuMeterDiskExtra*diskExtra; - MenuMeterNetExtra*netExtra; - MenuMeterMemExtra*memExtra; - MenuMetersPref*pref; +@implementation AppDelegate { + MenuMeterCPUExtra *cpuExtra; + MenuMeterDiskExtra *diskExtra; + MenuMeterNetExtra *netExtra; + MenuMeterMemExtra *memExtra; + MenuMetersPref *pref; #ifdef SPARKLE - SUUpdater*updater; + SUUpdater *updater; #endif - NSTimer*timer; + NSTimer *timer; } --(IBAction)checkForUpdates:(id)sender -{ +- (IBAction)checkForUpdates:(id)sender { #ifdef SPARKLE - [updater checkForUpdates:sender]; + [updater checkForUpdates:sender]; #endif } --(void)killOlderInstances{ - NSString*thisVersion=NSBundle.mainBundle.infoDictionary[@"CFBundleVersion"]; - for(NSRunningApplication* x in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.yujitach.MenuMeters"]){ - if([x isEqualTo:NSRunningApplication.currentApplication]){ - continue; - } - NSBundle*b=[NSBundle bundleWithURL:x.bundleURL]; - NSString*version=b.infoDictionary[@"CFBundleVersion"]; +- (void)killOlderInstances { + NSString *thisVersion = NSBundle.mainBundle.infoDictionary[@"CFBundleVersion"]; + for (NSRunningApplication *x in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.yujitach.MenuMeters"]) { + if ([x isEqualTo:NSRunningApplication.currentApplication]) { + continue; + } + NSBundle *b = [NSBundle bundleWithURL:x.bundleURL]; + NSString *version = b.infoDictionary[@"CFBundleVersion"]; #ifdef SPARKLE - NSComparisonResult r=[[SUStandardVersionComparator defaultComparator] compareVersion:version toVersion:thisVersion]; + NSComparisonResult r = [[SUStandardVersionComparator defaultComparator] compareVersion:version toVersion:thisVersion]; #else - NSComparisonResult r=[version compare:thisVersion options:NSNumericSearch]; + NSComparisonResult r = [version compare:thisVersion options:NSNumericSearch]; #endif - NSLog(@"vers: running is %@, ours is %@, compare result was %ld", version, thisVersion, r); - if(r!=NSOrderedDescending){ - NSLog(@"version %@ already running, which is equal or older than this binary %@. Going to kill it.",version,thisVersion); - [x terminate]; - } - } + NSLog(@"vers: running is %@, ours is %@, compare result was %ld", version, thisVersion, r); + if (r != NSOrderedDescending) { + NSLog(@"version %@ already running, which is equal or older than this binary %@. Going to kill it.", version, thisVersion); + [x terminate]; + } + } } -- (void)applicationWillFinishLaunching:(NSNotification *)notification -{ - [MenuMeterDefaults movePreferencesIfNecessary]; + +- (void)applicationWillFinishLaunching:(NSNotification *)notification { + [MenuMeterDefaults movePreferencesIfNecessary]; } #define WELCOME @"v2.0.8alert" + - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { - // Insert code here to initialize your application - [NSColor setIgnoresAlpha:NO]; - if([self isRunningOnReadOnlyVolume]){ - [self alertConcerningAppTranslocation]; - } - [self killOlderInstances]; + // Insert code here to initialize your application + [NSColor setIgnoresAlpha:NO]; + if ([self isRunningOnReadOnlyVolume]) { + [self alertConcerningAppTranslocation]; + } + [self killOlderInstances]; #ifdef SPARKLE - updater=[SUUpdater sharedUpdater]; - updater.feedURL=[NSURL URLWithString:@"https://member.ipmu.jp/yuji.tachikawa/MenuMetersElCapitan/MenuMeters-Update.xml"]; - pref=[[MenuMetersPref alloc] initWithAboutFileName:WELCOME andUpdater:updater]; + updater = [SUUpdater sharedUpdater]; + updater.feedURL = [NSURL URLWithString:@"https://member.ipmu.jp/yuji.tachikawa/MenuMetersElCapitan/MenuMeters-Update.xml"]; + pref = [[MenuMetersPref alloc] initWithAboutFileName:WELCOME andUpdater:updater]; #else - pref=[[MenuMetersPref alloc] initWithAboutFileName:WELCOME]; + pref = [[MenuMetersPref alloc] initWithAboutFileName:WELCOME]; #endif - NSString*key=[WELCOME stringByAppendingString:@"Presented"]; - if(![[NSUserDefaults standardUserDefaults] boolForKey:key]){ - [pref openAbout:WELCOME]; - [[NSUserDefaults standardUserDefaults] setBool:YES forKey:key]; - } - // init of extras were moved to the last step. - // It is because init of extras can raise exceptions when I introduce bugs. - // If extras are init'ed first, neither the updater nor the pref pane is init'ed, - // which is even worse. - // When extras are inited last, at least the updater and the pref pane are live. - cpuExtra=[[MenuMeterCPUExtra alloc] init]; - diskExtra=[[MenuMeterDiskExtra alloc] init]; - netExtra=[[MenuMeterNetExtra alloc] init]; - memExtra=[[MenuMeterMemExtra alloc] init]; + NSString *key = [WELCOME stringByAppendingString:@"Presented"]; + if (![[NSUserDefaults standardUserDefaults] boolForKey:key]) { + [pref openAbout:WELCOME]; + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:key]; + } + // init of extras were moved to the last step. + // It is because init of extras can raise exceptions when I introduce bugs. + // If extras are init'ed first, neither the updater nor the pref pane is init'ed, + // which is even worse. + // When extras are inited last, at least the updater and the pref pane are live. + cpuExtra = [[MenuMeterCPUExtra alloc] init]; + diskExtra = [[MenuMeterDiskExtra alloc] init]; + netExtra = [[MenuMeterNetExtra alloc] init]; + memExtra = [[MenuMeterMemExtra alloc] init]; } - - (void)applicationWillTerminate:(NSNotification *)aNotification { - // Insert code here to tear down your application + // Insert code here to tear down your application } - -- (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag -{ - [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - [pref.window makeKeyAndOrderFront:sender]; - return YES; +- (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag { + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + [pref.window makeKeyAndOrderFront:sender]; + return YES; } - - (BOOL)isRunningOnReadOnlyVolume { - // taken from https://github.com/Squirrel/Squirrel.Mac/pull/186/files - struct statfs statfsInfo; - NSURL *bundleURL = NSRunningApplication.currentApplication.bundleURL; - int result = statfs(bundleURL.fileSystemRepresentation, &statfsInfo); - if (result == 0) { - return (statfsInfo.f_flags & MNT_RDONLY) != 0; - } else { - // If we can't even check if the volume is read-only, assume it is. - return YES; - } + // taken from https://github.com/Squirrel/Squirrel.Mac/pull/186/files + struct statfs statfsInfo; + NSURL *bundleURL = NSRunningApplication.currentApplication.bundleURL; + int result = statfs(bundleURL.fileSystemRepresentation, &statfsInfo); + if (result == 0) { + return (statfsInfo.f_flags & MNT_RDONLY) != 0; + } + else { + // If we can't even check if the volume is read-only, assume it is. + return YES; + } } --(void)alertConcerningAppTranslocation{ - NSAlert*alert=[[NSAlert alloc] init]; - alert.messageText=@"Please move the app after downloading it"; - [alert addButtonWithTitle:@"OK, I quit the app and move it"]; - alert.informativeText=@"Please move the app to, say, /Applications, using your mouse/trackpad, not from the command line. \n\nApple decided that they don't allow the app to auto-update otherwise. \n\nI am sorry for the inconvenience."; - [alert runModal]; - [NSApp terminate:nil]; +- (void)alertConcerningAppTranslocation { + NSAlert *alert = [[NSAlert alloc] init]; + alert.messageText = NSLocalizedString(@"Please move the app after downloading it", @""); + [alert addButtonWithTitle:NSLocalizedString(@"OK, I quit the app and move it", @"")]; + alert.informativeText = NSLocalizedString(@"Please move the app to, say, /Applications, using your mouse/trackpad, not from the command line. \n\nApple decided that they don't allow the app to auto-update otherwise. \n\nI am sorry for the inconvenience.", @""); + [alert runModal]; + [NSApp terminate:nil]; } @end diff --git a/MenuMetersApp/Base.lproj/Localizable.strings b/MenuMetersApp/Base.lproj/Localizable.strings index 2eba768c..a1a7b08c 100644 --- a/MenuMetersApp/Base.lproj/Localizable.strings +++ b/MenuMetersApp/Base.lproj/Localizable.strings @@ -1,9 +1,9 @@ "Open MenuMeters preferences" = "Open MenuMeters preferences"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +// In the interest of improving localizability most strings in MenuMeters +// are exposed as NSString format strings, including the %1$, %2$ parameter placement +// convention. If localization requires different ordering of the parameters you +// can reorder the items (leaving the %1$ notations in place) and NSString will +// put the items in the right order // Processor title menu item (second title is used on multi-CPU systems) "Processor:" = "Processor:"; @@ -60,11 +60,11 @@ // Displayed when CPU load, load average, or task count fails to return info "No info available" = "No info available"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +// In the interest of improving localizability most strings in MenuMeters +// are exposed as NSString format strings, including the %1$, %2$ parameter placement +// convention. If localization requires different ordering of the parameters you +// can reorder the items (leaving the %1$ notations in place) and NSString will +// put the items in the right order // Strings used for disk space free/used/total labels // Note that the actual disk space float format is automatically localized @@ -79,11 +79,11 @@ "GB" = "GB"; "Memory Pressure:" = "Memory Pressure:"; "%@%%\t(level %@)" = "%@%%\t(level %@)"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +// In the interest of improving localizability most strings in MenuMeters +// are exposed as NSString format strings, including the %1$, %2$ parameter placement +// convention. If localization requires different ordering of the parameters you +// can reorder the items (leaving the %1$ notations in place) and NSString will +// put the items in the right order // Menubar display labels used in free/total mode "U:" = "U:"; @@ -139,11 +139,11 @@ "%@ total swap space" = "%1$@ total swap space"; // Swap space including used info (Tiger only) "%@ total swap space (%@ used)" = "%1$@ total swap space (%2$@ used)"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +// In the interest of improving localizability most strings in MenuMeters +// are exposed as NSString format strings, including the %1$, %2$ parameter placement +// convention. If localization requires different ordering of the parameters you +// can reorder the items (leaving the %1$ notations in place) and NSString will +// put the items in the right order // Menubar display labels for throughput, Tx and Rx also used for Tx and Rx menu items "Tx:" = "Tx:"; diff --git a/MenuMetersApp/en.lproj/Localizable.strings b/MenuMetersApp/en.lproj/Localizable.strings index 67380045..8b19e43e 100644 --- a/MenuMetersApp/en.lproj/Localizable.strings +++ b/MenuMetersApp/en.lproj/Localizable.strings @@ -1,214 +1,9 @@ -"Open MenuMeters preferences" = "Open MenuMeters preferences"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +/* No comment provided by engineer. */ +"OK, I quit the app and move it" = "OK, I quit the app and move it"; -// Processor title menu item (second title is used on multi-CPU systems) -"Processor:" = "Processor:"; -"Processors:" = "Processors:"; +/* No comment provided by engineer. */ +"Please move the app after downloading it" = "Please move the app after downloading it"; -// And the format string for the processor menu display (ex: "1 PowerPC 7450 @ 800MHz") -// Note that CPU name information ("PowerPC 7450") cannot be localized, it is -// provided by the system -"%u %@ @ %@" = "%1$u %2$@ @ %3$@"; +/* No comment provided by engineer. */ +"Please move the app to, say, /Applications, using your mouse/trackpad, not from the command line. \n\nApple decided that they don't allow the app to auto-update otherwise. \n\nI am sorry for the inconvenience." = "Please move the app to, say, /Applications, using your mouse/trackpad, not from the command line. \n\nApple decided that they don't allow the app to auto-update otherwise. \n\nI am sorry for the inconvenience."; -// Uptime title menu item -"Uptime:" = "Uptime:"; - -// Uptime error (unavailable) -"Unavailable" = "Unavailable"; - -// Format strings for uptime (ex: "2 days 08:16:32") -// Multiple day format -"%ld days %02ld:%02ld:%02ld" = "%1$ld days %2$02ld:%3$02ld:%4$02ld"; -// Single day format -"%ld day %02ld:%02ld:%02ld" = "%1$ld day %2$02ld:%3$02ld:%4$02ld"; -// Less than one day format -"%02ld:%02ld:%02ld" = "%1$02ld:%2$02ld:%3$02ld"; - -// Tasks and threads title -"Tasks/Threads:" = "Tasks/Threads:"; - -// Format string for tasks and threads -"%d tasks, %d threads" = "%1$d tasks, %2$d threads"; - -// Core count / hyperthreading format strings -" (%@ hyperthreads per core)" = " (%@ hyperthreads per core)"; -"%@%@ physical cores" = "%@%@ physical cores"; - -// Load average title -"Load Average (1m, 5m, 15m):" = "Load Average (1m, 5m, 15m):"; - -// Load average format -// Note that this only applies to the format of the string as a whole, not -// the format of the load average floats themselves (load average floats are -// automatically localized by NSNumberFormatter) -"%@, %@, %@" = "%1$@, %2$@, %3$@"; - -// CPU power limit status -"CPU power limit:" = "CPU power limit:"; -"speed %@%%, scheduler %@%%" = "speed %@%%, scheduler %@%%"; - -// Open Process Viewer/Open Console -"Open Process Viewer" = "Open Process Viewer"; -"Open Activity Monitor" = "Open Activity Monitor"; -"Open Console" = "Open Console"; - -// Miscellaneous error strings - -// Displayed when CPU load, load average, or task count fails to return info -"No info available" = "No info available"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order - -// Strings used for disk space free/used/total labels -// Note that the actual disk space float format is automatically localized -// by an NSNumberFormatter. -"%@ Used" = "%1$@ Used"; -"%@ Free" = "%1$@ Free"; -"%@ Total" = "%1$@ Total"; - -// Unit labels -"KB" = "KB"; -"MB" = "MB"; -"GB" = "GB"; -"Memory Pressure:" = "Memory Pressure:"; -"%@%%\t(level %@)" = "%@%%\t(level %@)"; - -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order - -// Menubar display labels used in free/total mode -"U:" = "U:"; -"F:" = "F:"; - -// Unit labels -"MB" = "MB"; - -// Memory usage title menu item -"Memory Usage:" = "Memory Usage:"; - -// Format string for memory usage. Float conversion to X.XX is -// automatically localized by NSNumberFormatter and is therefore not exposed -"%@ used, %@ free, %@ total" = "%1$@ used, %2$@ free, %3$@ total"; - -// Memory page statistics title menu item -"Memory Pages:" = "Memory Pages:"; - -// Format strings for memory statistics. Float conversion to X.XX is -// automatically localized by NSNumberFormatter and is therefore not exposed -"%@ active, %@ wired" = "%1$@ active, %2$@ wired"; -"%@ inactive, %@ free" = "%1$@ inactive, %2$@ free"; -"%@ compressed (%@)" = "%1$@ compressed (%2$@)"; - -// VM statistics title menu item -"VM Statistics:" = "VM Statistics:"; - -// Format strings for VM statistics -// Technically we should cover all permutations of 1 or more than 1 -// for each statistic, but in the real world users never have just -// one pagein or copy-on-write, etc. so we can simplify to just -// the plural forms -"%@ pageins, %@ pageouts" = "%1$@ pageins, %2$@ pageouts"; -"%@ cache lookups, %@ cache hits (%@)" = "%1$@ cache lookups, %2$@ cache hits (%3$@)"; -"%@ page faults, %@ copy-on-writes" = "%1$@ page faults, %2$@ copy-on-writes"; - -// Swap file statistics title menu item -"Swap Files:" = "Swap Files:"; - -// Swap file info formats. Here we do need to handle plurals since -// values of 1 are likely -// Basic swap file info (ex: "1 swap file in /private/var/vm/") -"%@ swap file present in %@" = "%1$@ swap file present in %2$@"; -"%@ swap files present in %@" = "%1$@ swap files present in %2$@"; -// Basic swap file info with encryption -"%@ encrypted swap file present in %@" = "%1$@ encrypted swap file present in %2$@"; -"%@ encrypted swap files present in %@" = "%1$@ encrypted swap files present in %2$@"; -// Maximum swap count info -"%@ swap file at peak usage" = "%1$@ swap file at peak usage"; -"%@ swap files at peak usage" = "%1$@ swap files at peak usage"; -// Swap space info, as with free/used/total the float format and MB label -// are handled automatically by NSFormatter -"%@ total swap space" = "%1$@ total swap space"; -// Swap space including used info (Tiger only) -"%@ total swap space (%@ used)" = "%1$@ total swap space (%2$@ used)"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order - -// Menubar display labels for throughput, Tx and Rx also used for Tx and Rx menu items -"Tx:" = "Tx:"; -"Rx:" = "Rx:"; - -// Unit labels -"Gbps" = "Gbps"; -"Mbps" = "Mbps"; -"Kbps" = "Kbps"; -"B" = "B"; -"KB" = "KB"; -"MB" = "MB"; -"GB" = "GB"; -"B/s" = "B/s"; -"KB/s" = "KB/s"; -"MB/s" = "MB/s"; -"GB/s" = "GB/s"; - -// PPP connection titles and states -"PPP:" = "PPP:"; -"Not Connected" = "Not Connected"; -"Connecting..." = "Connecting..."; -"Connected" = "Connected"; -"Connected %02d:%02d:%02d" = "Connected %1$02d:%2$02d:%3$02d"; -"Disconnecting..." = "Disconnecting..."; - -// TCP/IP menu titles -"TCP/IP:" = "TCP/IP:"; -"IPv4:" = "IPv4:"; -"IPv6:" = "IPv6:"; - -// Label for inactive TCP/IP interfaces -"Inactive" = "Inactive"; - -// AppleTalk menu title -"AppleTalk:" = "AppleTalk:"; - -// Format string for AppleTalk display info -"Net: %@ Node: %@ Zone: %@" = "Net: %1$@ Node: %2$@ Zone: %3$@"; - -// Throughput menu title -"Throughput:" = "Throughput:"; - -// Peak throughput menu title -"Peak Throughput:" = "Peak Throughput:"; - -// Traffic totals menu title -"Traffic Totals:" = "Traffic Totals:"; - -// Traffic total format string. The Tx and Rx labels from above are automatically used -// as the first param, and numbers are localized automatically by NSNumberFormatter -// ex: "Tx: XX.XMB (XXX,XXX bytes) -"%@ %@ (%@ bytes)" = "%1$@ %2$@ (%3$@ bytes)"; - -// Menu action title strings -"Open Network Utility" = "Open Network Utility"; -"Open Network Preferences" = "Open Network Preferences"; -"Open Internet Connect" = "Open Internet Connect"; -"Display primary interface" = "Display primary interface"; -"Display this interface" = "Display this interface"; -"Copy IPv4 address" = "Copy IPv4 address"; -"Copy IPv6 address" = "Copy IPv6 address"; -"Connect" = "Connect"; -"Disconnect" = "Disconnect"; - -// Miscellaneous error strings -"No Active Interfaces" = "No Active Interfaces"; diff --git a/MenuMetersApp/fi.lproj/Localizable.strings b/MenuMetersApp/fi.lproj/Localizable.strings index b7e3af4d..3f508bee 100644 --- a/MenuMetersApp/fi.lproj/Localizable.strings +++ b/MenuMetersApp/fi.lproj/Localizable.strings @@ -1,9 +1,9 @@ "Open MenuMeters preferences" = "Avaa MenuMetersin asetukset"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +// In the interest of improving localizability most strings in MenuMeters +// are exposed as NSString format strings, including the %1$, %2$ parameter placement +// convention. If localization requires different ordering of the parameters you +// can reorder the items (leaving the %1$ notations in place) and NSString will +// put the items in the right order // Processor title menu item (second title is used on multi-CPU systems) "Processor:" = "Processori:"; @@ -56,11 +56,11 @@ // Displayed when CPU load, load average, or task count fails to return info "No info available" = "Tietoa ei saatavilla"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +// In the interest of improving localizability most strings in MenuMeters +// are exposed as NSString format strings, including the %1$, %2$ parameter placement +// convention. If localization requires different ordering of the parameters you +// can reorder the items (leaving the %1$ notations in place) and NSString will +// put the items in the right order // Strings used for disk space free/used/total labels // Note that the actual disk space float format is automatically localized @@ -74,11 +74,11 @@ "MB" = " Mt"; "GB" = " Gt"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +// In the interest of improving localizability most strings in MenuMeters +// are exposed as NSString format strings, including the %1$, %2$ parameter placement +// convention. If localization requires different ordering of the parameters you +// can reorder the items (leaving the %1$ notations in place) and NSString will +// put the items in the right order // Menubar display labels used in free/total mode "U:" = "K:"; @@ -134,11 +134,11 @@ "%@ total swap space" = "%1$@ sivutustilaa yhteensä"; // Swap space including used info (Tiger only) "%@ total swap space (%@ used)" = "%1$@ sivutustilaa yhteensä (%2$@ käytössä)"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +// In the interest of improving localizability most strings in MenuMeters +// are exposed as NSString format strings, including the %1$, %2$ parameter placement +// convention. If localization requires different ordering of the parameters you +// can reorder the items (leaving the %1$ notations in place) and NSString will +// put the items in the right order // Menubar display labels for throughput, Tx and Rx also used for Tx and Rx menu items "Tx:" = "Läh:"; diff --git a/MenuMetersApp/it.lproj/Localizable.strings b/MenuMetersApp/it.lproj/Localizable.strings index 4a516bfd..b396929d 100644 --- a/MenuMetersApp/it.lproj/Localizable.strings +++ b/MenuMetersApp/it.lproj/Localizable.strings @@ -1,9 +1,9 @@ "Open MenuMeters preferences" = "Open MenuMeters preferences"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +// In the interest of improving localizability most strings in MenuMeters +// are exposed as NSString format strings, including the %1$, %2$ parameter placement +// convention. If localization requires different ordering of the parameters you +// can reorder the items (leaving the %1$ notations in place) and NSString will +// put the items in the right order // Processor title menu item (second title is used on multi-CPU systems) "Processor:" = "Processore:"; @@ -56,11 +56,11 @@ // Displayed when CPU load, load average, or task count fails to return info "No info available" = "Nessuna info disponibile"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +// In the interest of improving localizability most strings in MenuMeters +// are exposed as NSString format strings, including the %1$, %2$ parameter placement +// convention. If localization requires different ordering of the parameters you +// can reorder the items (leaving the %1$ notations in place) and NSString will +// put the items in the right order // Strings used for disk space free/used/total labels // Note that the actual disk space float format is automatically localized @@ -73,11 +73,11 @@ "KB" = "KB"; "MB" = "MB"; "GB" = "GB"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +// In the interest of improving localizability most strings in MenuMeters +// are exposed as NSString format strings, including the %1$, %2$ parameter placement +// convention. If localization requires different ordering of the parameters you +// can reorder the items (leaving the %1$ notations in place) and NSString will +// put the items in the right order // Menubar display labels used in free/total mode "U:" = "U:"; @@ -133,11 +133,11 @@ "%@ total swap space" = "%1$@ spazio swap totale"; // Swap space including used info (Tiger only) "%@ total swap space (%@ used)" = "%1$@ spazio swap totale (%2$@ usato)"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +// In the interest of improving localizability most strings in MenuMeters +// are exposed as NSString format strings, including the %1$, %2$ parameter placement +// convention. If localization requires different ordering of the parameters you +// can reorder the items (leaving the %1$ notations in place) and NSString will +// put the items in the right order // Menubar display labels for throughput, Tx and Rx also used for Tx and Rx menu items "Tx:" = "Tx:"; diff --git a/MenuMetersApp/main.m b/MenuMetersApp/main.m index 8c42d27c..c24708e8 100644 --- a/MenuMetersApp/main.m +++ b/MenuMetersApp/main.m @@ -8,6 +8,6 @@ #import -int main(int argc, const char * argv[]) { - return NSApplicationMain(argc, argv); +int main(int argc, const char *argv[]) { + return NSApplicationMain(argc, argv); } diff --git a/MenuMetersApp/nl.lproj/Localizable.strings b/MenuMetersApp/nl.lproj/Localizable.strings index 9ea3f630..30f848ad 100644 --- a/MenuMetersApp/nl.lproj/Localizable.strings +++ b/MenuMetersApp/nl.lproj/Localizable.strings @@ -1,9 +1,9 @@ "Open MenuMeters preferences" = "Open MenuMeters preferences"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +// In the interest of improving localizability most strings in MenuMeters +// are exposed as NSString format strings, including the %1$, %2$ parameter placement +// convention. If localization requires different ordering of the parameters you +// can reorder the items (leaving the %1$ notations in place) and NSString will +// put the items in the right order // Processor title menu item (second title is used on multi-CPU systems) "Processor:" = "Processor:"; @@ -56,11 +56,11 @@ // Displayed when CPU load, load average, or task count fails to return info "No info available" = "Geen informatie beschikbaar"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +// In the interest of improving localizability most strings in MenuMeters +// are exposed as NSString format strings, including the %1$, %2$ parameter placement +// convention. If localization requires different ordering of the parameters you +// can reorder the items (leaving the %1$ notations in place) and NSString will +// put the items in the right order // Strings used for disk space free/used/total labels // Note that the actual disk space float format is automatically localized @@ -74,11 +74,11 @@ "MB" = "MB"; "GB" = "GB"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +// In the interest of improving localizability most strings in MenuMeters +// are exposed as NSString format strings, including the %1$, %2$ parameter placement +// convention. If localization requires different ordering of the parameters you +// can reorder the items (leaving the %1$ notations in place) and NSString will +// put the items in the right order // Menubar display labels used in free/total mode "U:" = "G:"; @@ -134,11 +134,11 @@ "%@ total swap space" = "%1$@ in gebruik voor swap-bestanden"; // Swap space including used info (Tiger only) "%@ total swap space (%@ used)" = "%1$@ in gebruik voor swap-bestanden (%2$@ in gebruik)"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +// In the interest of improving localizability most strings in MenuMeters +// are exposed as NSString format strings, including the %1$, %2$ parameter placement +// convention. If localization requires different ordering of the parameters you +// can reorder the items (leaving the %1$ notations in place) and NSString will +// put the items in the right order // Menubar display labels for throughput, Tx and Rx also used for Tx and Rx menu items "Tx:" = "Tx:"; diff --git a/MenuMetersApp/zh-Hans.lproj/Localizable.strings b/MenuMetersApp/zh-Hans.lproj/Localizable.strings index 8965b7dd..77a18903 100644 --- a/MenuMetersApp/zh-Hans.lproj/Localizable.strings +++ b/MenuMetersApp/zh-Hans.lproj/Localizable.strings @@ -1,9 +1,9 @@ "Open MenuMeters preferences" = "Open MenuMeters preferences"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +// In the interest of improving localizability most strings in MenuMeters +// are exposed as NSString format strings, including the %1$, %2$ parameter placement +// convention. If localization requires different ordering of the parameters you +// can reorder the items (leaving the %1$ notations in place) and NSString will +// put the items in the right order // Processor title menu item (second title is used on multi-CPU systems) "Processor:" = "处理器:"; @@ -56,11 +56,11 @@ // Displayed when CPU load, load average, or task count fails to return info "No info available" = "无可用信息"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +// In the interest of improving localizability most strings in MenuMeters +// are exposed as NSString format strings, including the %1$, %2$ parameter placement +// convention. If localization requires different ordering of the parameters you +// can reorder the items (leaving the %1$ notations in place) and NSString will +// put the items in the right order // Strings used for disk space free/used/total labels // Note that the actual disk space float format is automatically localized @@ -73,11 +73,11 @@ "KB" = "KB"; "MB" = "MB"; "GB" = "GB"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +// In the interest of improving localizability most strings in MenuMeters +// are exposed as NSString format strings, including the %1$, %2$ parameter placement +// convention. If localization requires different ordering of the parameters you +// can reorder the items (leaving the %1$ notations in place) and NSString will +// put the items in the right order // Menubar display labels used in free/total mode "U:" = "用:"; @@ -133,11 +133,11 @@ "%@ total swap space" = "%1$@ 合计交换空间"; // Swap space including used info (Tiger only) "%@ total swap space (%@ used)" = "%1$@ 合计交换空间 (%2$@ 已使用)"; -// In the interest of improving localizability most strings in MenuMeters -// are exposed as NSString format strings, including the %1$, %2$ parameter placement -// convention. If localization requires different ordering of the parameters you -// can reorder the items (leaving the %1$ notations in place) and NSString will -// put the items in the right order +// In the interest of improving localizability most strings in MenuMeters +// are exposed as NSString format strings, including the %1$, %2$ parameter placement +// convention. If localization requires different ordering of the parameters you +// can reorder the items (leaving the %1$ notations in place) and NSString will +// put the items in the right order // Menubar display labels for throughput, Tx and Rx also used for Tx and Rx menu items "Tx:" = "发:"; diff --git a/MenuMetersMenuExtraBase.h b/MenuMetersMenuExtraBase.h index 9b753c87..c04f5ad2 100644 --- a/MenuMetersMenuExtraBase.h +++ b/MenuMetersMenuExtraBase.h @@ -6,35 +6,47 @@ // // -#import #import "LocalizedStrings.h" +#import @class MenuMeterDefaults; -@interface MenuMetersMenuExtraBase : NSObject -{ - NSStatusItem* statusItem; - NSTimer* updateTimer; +@interface MenuMetersMenuExtraBase : NSObject { + NSStatusItem *statusItem; + NSTimer *updateTimer; } --(NSColor*)colorByAdjustingForLightDark:(NSColor*)c; -- (NSImage*)image; -- (NSMenu*)menu; -- (void)configDisplay:(NSString*)bundleID fromPrefs:(MenuMeterDefaults*)ourPrefs withTimerInterval:(NSTimeInterval)interval; -- (void)configFromPrefs:(NSNotification*)notification; + +- (NSColor *)colorByAdjustingForLightDark:(NSColor *)c; + +- (NSImage *)image; + +- (NSMenu *)menu; + +- (void)configDisplay:(NSString *)bundleID fromPrefs:(MenuMeterDefaults *)ourPrefs withTimerInterval:(NSTimeInterval)interval; + +- (void)configFromPrefs:(NSNotification *)notification; + - (void)timerFired:(id)timer; + - (void)openMenuMetersPref:(id)sender; + - (void)openActivityMonitor:(id)sender; -- (void)addStandardMenuEntriesTo:(NSMenu*)extraMenu; + +- (void)addStandardMenuEntriesTo:(NSMenu *)extraMenu; + - (void)setupAppearance; + - (BOOL)isDark; + - (CGFloat)height; --(NSColor*)menuBarTextColor; --(instancetype)initWithBundleID:(NSString*)bundleID; -@property(nonatomic, readonly) BOOL isMenuVisible; -@property(nonatomic, retain) NSString*bundleID; + +- (NSColor *)menuBarTextColor; + +- (instancetype)initWithBundleID:(NSString *)bundleID; +@property (nonatomic, readonly) BOOL isMenuVisible; +@property (nonatomic, retain) NSString *bundleID; @end #define NSMenuExtra MenuMetersMenuExtraBase -#define kOpenMenuMetersPref @"Open MenuMeters preferences" -#define kOpenActivityMonitorTitle @"Open Activity Monitor" - +#define kOpenMenuMetersPref @"Open MenuMeters preferences" +#define kOpenActivityMonitorTitle @"Open Activity Monitor" diff --git a/MenuMetersMenuExtraBase.m b/MenuMetersMenuExtraBase.m index afacd8ed..06341d26 100644 --- a/MenuMetersMenuExtraBase.m +++ b/MenuMetersMenuExtraBase.m @@ -14,238 +14,246 @@ #import "MenuMeterMemExtra.h" #import "MenuMeterNetExtra.h" -#define kAppleInterfaceThemeChangedNotification @"AppleInterfaceThemeChangedNotification" +#define kAppleInterfaceThemeChangedNotification @"AppleInterfaceThemeChangedNotification" @implementation MenuMetersMenuExtraBase --(NSColor*)colorByAdjustingForLightDark:(NSColor*)c -{ - return [c blendedColorWithFraction:[[NSUserDefaults standardUserDefaults] floatForKey:@"tintPercentage"]/100 ofColor:self.isDark?[[NSColor whiteColor] colorWithAlphaComponent:[c alphaComponent]]:[[NSColor blackColor] colorWithAlphaComponent:[c alphaComponent]]]; -} --(instancetype)initWithBundleID:(NSString*)bundleID -{ - self=[super init]; - self.bundleID=bundleID; - // Register for pref changes - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(configFromPrefs:) - name:self.bundleID - object:kPrefChangeNotification]; - [[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:@"tintPercentage" options:NSKeyValueObservingOptionNew context:nil]; - if(@available(macOS 10.14,*)){ - }else{ - [[NSDistributedNotificationCenter defaultCenter] addObserver:self - selector:@selector(configFromPrefs:) - name:kAppleInterfaceThemeChangedNotification - object:nil]; - } - return self; -} --(void)configFromPrefs:(NSNotification *)notification -{ - NSLog(@"shouldn't happen"); - abort(); -} --(NSMenu*)menu -{ - NSLog(@"shouldn't happen"); - abort(); -} --(NSImage*)image -{ - NSLog(@"shouldn't happen"); - abort(); -} --(void)timerFired:(id)notused -{ - statusItem.button.image=self.image; -/* NSImage*image=self.image; - NSImage*canvas=[NSImage imageWithSize:image.size flipped:NO drawingHandler:^BOOL(NSRect dstRect) { - [[[NSColor systemGrayColor] colorWithAlphaComponent:.3] setFill]; - [NSBezierPath fillRect:(CGRect) {.size = image.size}]; - [image drawAtPoint:CGPointZero fromRect:(CGRect) {.size = image.size} operation:NSCompositeSourceOver fraction:1.0]; - return YES; - }]; - statusItem.button.image=canvas;*/ -} --(void)timerXired:(id)notused -{ - NSImage *oldCanvas = statusItem.button.image; - NSImage *canvas = oldCanvas; - NSImage *image = self.image; - NSSize imageSize = image.size; - NSSize oldImageSize = canvas.size; - if (imageSize.width != oldImageSize.width || imageSize.height != oldImageSize.height) { - canvas = [[NSImage alloc] initWithSize:imageSize]; - } - - [canvas lockFocus]; - [image drawAtPoint:CGPointZero fromRect:(CGRect) {.size = image.size} operation:NSCompositeCopy fraction:1.0]; - [canvas unlockFocus]; - - if (canvas != oldCanvas) { - statusItem.button.image = canvas; - } else { - [statusItem.button displayRectIgnoringOpacity:statusItem.button.bounds]; - } -} -- (void)configDisplay:(NSString*)bundleID fromPrefs:(MenuMeterDefaults*)ourPrefs withTimerInterval:(NSTimeInterval)interval -{ - if([ourPrefs loadBoolPref:bundleID defaultValue:YES]){ - if(!statusItem){ - statusItem=[[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength]; - if(@available(macOS 11,*)){ - // 11.0.1 does not keep the position unless autosaveName is explicitly set, - // see https://github.com/feedback-assistant/reports/issues/151 . - // This is done here in order not to lose positions on pre-macOS 11 systems. - statusItem.autosaveName=self.bundleID; - } - if(@available(macOS 10.12,*)){ - statusItem.behavior=NSStatusItemBehaviorRemovalAllowed; - [statusItem addObserver:self forKeyPath:@"visible" options:NSKeyValueObservingOptionNew context:nil]; - } - statusItem.menu = self.menu; - statusItem.menu.delegate = self; - [statusItem.button addObserver:self forKeyPath:@"effectiveAppearance" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil]; - } - [updateTimer invalidate]; - updateTimer=[NSTimer timerWithTimeInterval:interval target:self selector:@selector(timerFired:) userInfo:nil repeats:YES]; - [updateTimer setTolerance:.2*interval]; - [[NSRunLoop currentRunLoop] addTimer:updateTimer forMode:NSRunLoopCommonModes]; - }else if(![ourPrefs loadBoolPref:bundleID defaultValue:YES] && statusItem){ - [self removeStatusItem]; - } -} --(void)removeStatusItem -{ - [updateTimer invalidate]; - [[NSStatusBar systemStatusBar] removeStatusItem:statusItem]; - statusItem=nil; - [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"menuExtraUnloaded" object:self.bundleID]]; -} --(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context -{ - if(object==statusItem.button && [keyPath isEqualToString:@"effectiveAppearance"]){ - NSAppearance*old=change[NSKeyValueChangeOldKey]; - NSAppearance*new=change[NSKeyValueChangeNewKey]; - if(![old.name isEqualToString:new.name]){ - [self configFromPrefs:nil]; - } - } - - if(@available(macOS 10.12,*)){ - if(object==statusItem && [keyPath isEqualToString:@"visible"]){ - if(!statusItem.visible){ - [self removeStatusItem]; - } - } - } - if([keyPath isEqualToString:@"tintPercentage"]){ - [self configFromPrefs:nil]; - } -} -- (void)openMenuMetersPref:(id)sender -{ - [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"openPref" object:self]]; + +- (NSColor *)colorByAdjustingForLightDark:(NSColor *)c { + return [c blendedColorWithFraction:[[NSUserDefaults standardUserDefaults] floatForKey:@"tintPercentage"] / 100 ofColor:[NSColor colorWithWhite:self.isDark alpha:[c alphaComponent]]]; +} + +- (instancetype)initWithBundleID:(NSString *)bundleID { + self = [super init]; + self.bundleID = bundleID; + // Register for pref changes + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(configFromPrefs:) + name:self.bundleID + object:kPrefChangeNotification]; + [[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:@"tintPercentage" options:NSKeyValueObservingOptionNew context:nil]; + if (@available(macOS 10.14, *)) { + } + else { + [[NSDistributedNotificationCenter defaultCenter] addObserver:self + selector:@selector(configFromPrefs:) + name:kAppleInterfaceThemeChangedNotification + object:nil]; + } + return self; +} + +- (void)configFromPrefs:(NSNotification *)notification { + NSLog(@"shouldn't happen"); + abort(); +} + +- (NSMenu *)menu { + NSLog(@"shouldn't happen"); + abort(); +} + +- (NSImage *)image { + NSLog(@"shouldn't happen"); + abort(); +} + +- (void)timerFired:(id)notused { + statusItem.button.image = self.image; + /* NSImage*image=self.image; + NSImage*canvas=[NSImage imageWithSize:image.size flipped:NO drawingHandler:^BOOL(NSRect dstRect) { + [[[NSColor systemGrayColor] colorWithAlphaComponent:.3] setFill]; + [NSBezierPath fillRect:(CGRect) {.size = image.size}]; + [image drawAtPoint:CGPointZero fromRect:(CGRect) {.size = image.size} operation:NSCompositeSourceOver fraction:1.0]; + return YES; + }]; + statusItem.button.image=canvas;*/ +} + +- (void)timerXired:(id)notused { + NSImage *oldCanvas = statusItem.button.image; + NSImage *canvas = oldCanvas; + NSImage *image = self.image; + NSSize imageSize = image.size; + NSSize oldImageSize = canvas.size; + if (imageSize.width != oldImageSize.width || imageSize.height != oldImageSize.height) { + canvas = [[NSImage alloc] initWithSize:imageSize]; + } + + [canvas lockFocus]; + [image drawAtPoint:CGPointZero fromRect:(CGRect){.size = image.size} operation:NSCompositeCopy fraction:1.0]; + [canvas unlockFocus]; + + if (canvas != oldCanvas) { + statusItem.button.image = canvas; + } + else { + [statusItem.button displayRectIgnoringOpacity:statusItem.button.bounds]; + } +} + +- (void)configDisplay:(NSString *)bundleID fromPrefs:(MenuMeterDefaults *)ourPrefs withTimerInterval:(NSTimeInterval)interval { + if ([ourPrefs loadBoolPref:bundleID defaultValue:YES]) { + if (!statusItem) { + statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength]; + if (@available(macOS 11, *)) { + // 11.0.1 does not keep the position unless autosaveName is explicitly set, + // see https://github.com/feedback-assistant/reports/issues/151 . + // This is done here in order not to lose positions on pre-macOS 11 systems. + statusItem.autosaveName = self.bundleID; + } + if (@available(macOS 10.12, *)) { + statusItem.behavior = NSStatusItemBehaviorRemovalAllowed; + [statusItem addObserver:self forKeyPath:@"visible" options:NSKeyValueObservingOptionNew context:nil]; + } + statusItem.menu = self.menu; + statusItem.menu.delegate = self; + [statusItem.button addObserver:self forKeyPath:@"effectiveAppearance" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil]; + } + [updateTimer invalidate]; + updateTimer = [NSTimer timerWithTimeInterval:interval target:self selector:@selector(timerFired:) userInfo:nil repeats:YES]; + [updateTimer setTolerance:.2 * interval]; + [[NSRunLoop currentRunLoop] addTimer:updateTimer forMode:NSRunLoopCommonModes]; + } + else if (![ourPrefs loadBoolPref:bundleID defaultValue:YES] && statusItem) { + [self removeStatusItem]; + } +} + +- (void)removeStatusItem { + [updateTimer invalidate]; + [[NSStatusBar systemStatusBar] removeStatusItem:statusItem]; + statusItem = nil; + [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"menuExtraUnloaded" object:self.bundleID]]; } + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { + if (object == statusItem.button && [keyPath isEqualToString:@"effectiveAppearance"]) { + NSAppearance *old = change[NSKeyValueChangeOldKey]; + NSAppearance *new = change[NSKeyValueChangeNewKey]; + if (![old.name isEqualToString:new.name]) { + [self configFromPrefs:nil]; + } + } + + if (@available(macOS 10.12, *)) { + if (object == statusItem && [keyPath isEqualToString:@"visible"]) { + if (!statusItem.visible) { + [self removeStatusItem]; + } + } + } + if ([keyPath isEqualToString:@"tintPercentage"]) { + [self configFromPrefs:nil]; + } +} + +- (void)openMenuMetersPref:(id)sender { + [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"openPref" object:self]]; +} + - (void)openActivityMonitor:(id)sender { - if (![[NSWorkspace sharedWorkspace] launchApplication:@"Activity Monitor.app"]) { - NSLog(@"MenuMeter unable to launch the Activity Monitor."); - } - BOOL x=[[NSUserDefaults standardUserDefaults] boolForKey:@"activityMonitorOpenSpecificPanes"]; - if(!x) - return; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(),^{ -// if(@available(macOS 10.15,*)){ - int tab=1; - if([self isKindOfClass:[MenuMeterCPUExtra class]]){ - tab=1; - } - // on some Mac's there is a "GPU" tab at the 2nd position. - // So the rest needs to be addressed from the last - if([self isKindOfClass:[MenuMeterDiskExtra class]]){ - tab=-2; - } - if([self isKindOfClass:[MenuMeterMemExtra class]]){ - tab=-4; - } - if([self isKindOfClass:[MenuMeterNetExtra class]]){ - tab=-1; - } - NSString*source=[NSString stringWithFormat:@"tell application \"System Events\" to tell process \"Activity Monitor\" to click radio button %@ of radio group 1 of group 2 of toolbar of window 1", @(tab)]; - NSAppleScript*script=[[NSAppleScript alloc] initWithSource:source]; - NSDictionary* errorDict=nil; - [script executeAndReturnError:&errorDict]; - if(errorDict){ - NSLog(@"%@",errorDict); - } -// } - }); + if (![[NSWorkspace sharedWorkspace] launchApplication:@"Activity Monitor.app"]) { + NSLog(@"MenuMeter unable to launch the Activity Monitor."); + } + BOOL x = [[NSUserDefaults standardUserDefaults] boolForKey:@"activityMonitorOpenSpecificPanes"]; + if (!x) + return; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ + // if(@available(macOS 10.15,*)){ + int tab = 1; + if ([self isKindOfClass:[MenuMeterCPUExtra class]]) { + tab = 1; + } + // on some Mac's there is a "GPU" tab at the 2nd position. + // So the rest needs to be addressed from the last + if ([self isKindOfClass:[MenuMeterDiskExtra class]]) { + tab = -2; + } + if ([self isKindOfClass:[MenuMeterMemExtra class]]) { + tab = -4; + } + if ([self isKindOfClass:[MenuMeterNetExtra class]]) { + tab = -1; + } + NSString *source = [NSString stringWithFormat:@"tell application \"System Events\" to tell process \"Activity Monitor\" to click radio button %@ of radio group 1 of group 2 of toolbar of window 1", @(tab)]; + NSAppleScript *script = [[NSAppleScript alloc] initWithSource:source]; + NSDictionary *errorDict = nil; + [script executeAndReturnError:&errorDict]; + if (errorDict) { + NSLog(@"%@", errorDict); + } + // } + }); } // openActivityMonitor -- (void)addStandardMenuEntriesTo:(NSMenu*)extraMenu -{ - NSMenuItem* menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:NSLocalizedString(kOpenActivityMonitorTitle, kOpenActivityMonitorTitle) - action:@selector(openActivityMonitor:) - keyEquivalent:@""]; - [menuItem setTarget:self]; - menuItem = (NSMenuItem *)[extraMenu addItemWithTitle:NSLocalizedString(kOpenMenuMetersPref, kOpenMenuMetersPref) - action:@selector(openMenuMetersPref:) - keyEquivalent:@""]; - [menuItem setTarget:self]; - -} --(BOOL)isDark -{ - if(@available(macOS 10.14,*)){ - // https://github.com/ruiaureliano/macOS-Appearance/blob/master/Appearance/Source/AppDelegate.swift - return [statusItem.button.effectiveAppearance.name containsString:@"ark"]; - }else{ - // https://stackoverflow.com/questions/25207077/how-to-detect-if-os-x-is-in-dark-mode - // On 10.10 there is no documented API for theme, so we'll guess a couple of different ways. - BOOL isDark = NO; - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - [defaults synchronize]; - NSString *interfaceStyle = [defaults stringForKey:@"AppleInterfaceStyle"]; - if (interfaceStyle && [interfaceStyle isEqualToString:@"Dark"]) { - isDark = YES; - } - return isDark; - } -} --(NSColor*)menuBarTextColor -{ - if(@available(macOS 10.14,*)){ - return [NSColor labelColor]; - } - if (self.isDark){ - return [NSColor whiteColor]; - } - return [NSColor blackColor]; -} --(CGFloat)height -{ - CGFloat height=statusItem.button.frame.size.height; - // height is sometimes zero here, which causes a lot of headaches if untreated... - if(height<10){ - height=22; // the value before Big Sur. - } - return height; + +- (void)addStandardMenuEntriesTo:(NSMenu *)extraMenu { + NSMenuItem *menuItem = [extraMenu addItemWithTitle:NSLocalizedString(kOpenActivityMonitorTitle, kOpenActivityMonitorTitle) + action:@selector(openActivityMonitor:) + keyEquivalent:@""]; + [menuItem setTarget:self]; + menuItem = [extraMenu addItemWithTitle:NSLocalizedString(kOpenMenuMetersPref, kOpenMenuMetersPref) + action:@selector(openMenuMetersPref:) + keyEquivalent:@""]; + [menuItem setTarget:self]; +} + +- (BOOL)isDark { + if (@available(macOS 10.14, *)) { + // https://github.com/ruiaureliano/macOS-Appearance/blob/master/Appearance/Source/AppDelegate.swift + return [statusItem.button.effectiveAppearance.name containsString:@"ark"]; + } + else { + // https://stackoverflow.com/questions/25207077/how-to-detect-if-os-x-is-in-dark-mode + // On 10.10 there is no documented API for theme, so we'll guess a couple of different ways. + BOOL isDark = NO; + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults synchronize]; + NSString *interfaceStyle = [defaults stringForKey:@"AppleInterfaceStyle"]; + if (interfaceStyle && [interfaceStyle isEqualToString:@"Dark"]) { + isDark = YES; + } + return isDark; + } +} + +- (NSColor *)menuBarTextColor { + if (@available(macOS 10.14, *)) { + return [NSColor labelColor]; + } + if (self.isDark) { + return [NSColor whiteColor]; + } + return [NSColor blackColor]; +} + +- (CGFloat)height { + CGFloat height = statusItem.button.frame.size.height; + // height is sometimes zero here, which causes a lot of headaches if untreated... + if (height < 10) { + height = 22; // the value before Big Sur. + } + return height; } + - (void)setupAppearance { - if(@available(macOS 10.14,*)){ - [NSAppearance setCurrentAppearance:statusItem.button.effectiveAppearance]; - } + if (@available(macOS 10.14, *)) { + [NSAppearance setCurrentAppearance:statusItem.button.effectiveAppearance]; + } } #pragma mark NSMenuDelegate -- (void)menuNeedsUpdate:(NSMenu*)menu { - statusItem.menu = self.menu; - statusItem.menu.delegate = self; + +- (void)menuNeedsUpdate:(NSMenu *)menu { + statusItem.menu = self.menu; + statusItem.menu.delegate = self; } -- (void)menuWillOpen:(NSMenu*)menu { - _isMenuVisible = YES; + +- (void)menuWillOpen:(NSMenu *)menu { + _isMenuVisible = YES; } -- (void)menuDidClose:(NSMenu*)menu { - _isMenuVisible = NO; + +- (void)menuDidClose:(NSMenu *)menu { + _isMenuVisible = NO; } @end diff --git a/PrefPane/Base.lproj/MenuMetersPref.xib b/PrefPane/Base.lproj/MenuMetersPref.xib index 6709caf0..41f74952 100644 --- a/PrefPane/Base.lproj/MenuMetersPref.xib +++ b/PrefPane/Base.lproj/MenuMetersPref.xib @@ -1,8 +1,8 @@ - + - + @@ -25,16 +25,14 @@ - - - - + + @@ -92,30 +90,27 @@ - - + + - - - + + + - - - + + - + - - - + + - - - + + @@ -132,10 +127,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -232,9 +154,8 @@ - - - + + @@ -242,18 +163,16 @@ - - - - + + + - - - + + @@ -261,61 +180,91 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + - - - + + @@ -323,9 +272,8 @@ - - - - - - - - - - - - - - - - - + + @@ -357,53 +291,56 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + @@ -421,33 +358,16 @@ - - - - - - - - + + + - - - - + + @@ -463,27 +383,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - + - + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - + + - - - - - + + + + + - - - - - + + + + - + - - + - + - - - - + + + + + + - - - - + + + - - - - - + + + + - + - + + - + - - - + + + + + + + + + + @@ -629,97 +656,60 @@ - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -736,252 +726,414 @@ - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -996,18 +1148,16 @@ - - - - + + + - - - + + @@ -1024,18 +1174,16 @@ - - - - + + + - - - + + @@ -1050,31 +1198,16 @@ - - - - + + + - - - - - - - - - - - - - - - - + + @@ -1088,57 +1221,16 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - + + @@ -1155,27 +1247,24 @@ - - - + + - - - + + - - - - - - - - - - - - - + + @@ -1213,44 +1292,80 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + @@ -1270,9 +1385,8 @@ - - - - - + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - + + - - + + - + - + + + + - + - - - + + - - - - + + + - - - + + - - - + + - - - + + - - - + + @@ -1407,9 +1593,8 @@ - - - - - + + - - - + + @@ -1448,15 +1630,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/PrefPane/EMCLoginItem.h b/PrefPane/EMCLoginItem.h index fd0a1451..5f637211 100644 --- a/PrefPane/EMCLoginItem.h +++ b/PrefPane/EMCLoginItem.h @@ -10,20 +10,31 @@ @interface EMCLoginItem : NSObject - (instancetype)init; + - (instancetype)initWithBundle:(NSBundle *)bundle; + - (instancetype)initWithPath:(NSString *)path; - (BOOL)isLoginItem; + - (void)addLoginItem; + - (void)removeLoginItem; + - (void)addAfterLast; + - (void)addAfterFirst; + - (void)addAfterItemWithPath:(NSString *)path; + - (void)addAfterBundle:(NSBundle *)bundle; + - (void)setIconRef:(IconRef)iconRef; + (instancetype)loginItem; + + (instancetype)loginItemWithBundle:(NSBundle *)bundle; + + (instancetype)loginItemWithPath:(NSString *)path; @end diff --git a/PrefPane/EMCLoginItem.m b/PrefPane/EMCLoginItem.m index 4fe4044e..c26d182c 100644 --- a/PrefPane/EMCLoginItem.m +++ b/PrefPane/EMCLoginItem.m @@ -12,319 +12,274 @@ #error This class requires ARC support to be enabled. #endif -@implementation EMCLoginItem -{ - CFURLRef url; - LSSharedFileListItemRef itemBeforeInsertion; - CFURLRef itemBeforePath; - IconRef _iconRef; +@implementation EMCLoginItem { + CFURLRef url; + LSSharedFileListItemRef itemBeforeInsertion; + CFURLRef itemBeforePath; + IconRef _iconRef; } -- (id)init -{ - self = [super init]; - - if (self) - { - NSString * appPath = [[NSBundle mainBundle] bundlePath]; - [self initHelper:appPath]; - } - - return self; +- (instancetype)init { + self = [super init]; + + if (self) { + NSString *appPath = [[NSBundle mainBundle] bundlePath]; + [self initHelper:appPath]; + } + + return self; } -- (void)dealloc -{ - if (_iconRef) - { - ReleaseIconRef(_iconRef); - } +- (void)dealloc { + if (_iconRef) { + ReleaseIconRef(_iconRef); + } } -- (instancetype)initWithBundle:(NSBundle *)bundle -{ - if (!bundle) - { - NSException* nullException = [NSException - exceptionWithName:@"NullPointerException" - reason:@"Bundle cannot be null." - userInfo:nil]; - @throw nullException; - } - - self = [super init]; - - if (self) - { - NSString * appPath = [bundle bundlePath]; - [self initHelper:appPath]; - } - - return self; +- (instancetype)initWithBundle:(NSBundle *)bundle { + if (!bundle) { + NSException *nullException = [NSException + exceptionWithName:@"NullPointerException" + reason:@"Bundle cannot be null." + userInfo:nil]; + @throw nullException; + } + + self = [super init]; + + if (self) { + NSString *appPath = [bundle bundlePath]; + [self initHelper:appPath]; + } + + return self; } -- (instancetype)initWithPath:(NSString *)appPath -{ - if (!appPath) - { - NSException* nullException = [NSException - exceptionWithName:@"NullPointerException" - reason:@"Path cannot be null." - userInfo:nil]; - @throw nullException; - } - - self = [super init]; - - if (self) - { - [self initHelper:appPath]; - } - - return self; +- (instancetype)initWithPath:(NSString *)appPath { + if (!appPath) { + NSException *nullException = [NSException + exceptionWithName:@"NullPointerException" + reason:@"Path cannot be null." + userInfo:nil]; + @throw nullException; + } + + self = [super init]; + + if (self) { + [self initHelper:appPath]; + } + + return self; } -- (void)initHelper:(NSString *)appPath -{ - url = (CFURLRef)CFBridgingRetain([NSURL fileURLWithPath:appPath]); - itemBeforeInsertion = kLSSharedFileListItemLast; +- (void)initHelper:(NSString *)appPath { + url = (CFURLRef)CFBridgingRetain([NSURL fileURLWithPath:appPath]); + itemBeforeInsertion = kLSSharedFileListItemLast; } -+ (instancetype)loginItem -{ - return [[EMCLoginItem alloc] initWithBundle:[NSBundle mainBundle]]; ++ (instancetype)loginItem { + return [[EMCLoginItem alloc] initWithBundle:[NSBundle mainBundle]]; } -+ (instancetype)loginItemWithBundle:(NSBundle *)bundle -{ - return [[EMCLoginItem alloc] initWithBundle:bundle]; ++ (instancetype)loginItemWithBundle:(NSBundle *)bundle { + return [[EMCLoginItem alloc] initWithBundle:bundle]; } -+ (instancetype)loginItemWithPath:(NSString *)path -{ - return [[EMCLoginItem alloc] initWithPath:path]; ++ (instancetype)loginItemWithPath:(NSString *)path { + return [[EMCLoginItem alloc] initWithPath:path]; } -- (void)setIconRef:(IconRef)iconRef -{ - if (_iconRef == iconRef) - { - return; - } - - if (_iconRef) - { - ReleaseIconRef(_iconRef); - } - - if (AcquireIconRef(iconRef) == noErr) - { - _iconRef = iconRef; - } - else - { - NSLog(@"Error: Cannot acquire IconRef."); - _iconRef = nil; - } +- (void)setIconRef:(IconRef)iconRef { + if (_iconRef == iconRef) { + return; + } + + if (_iconRef) { + ReleaseIconRef(_iconRef); + } + + if (AcquireIconRef(iconRef) == noErr) { + _iconRef = iconRef; + } + else { + NSLog(@"Error: Cannot acquire IconRef."); + _iconRef = nil; + } } -- (BOOL)isLoginItem -{ - LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, - kLSSharedFileListSessionLoginItems, - NULL); - - if (loginItems) - { - UInt32 seed; - CFArrayRef loginItemsArray = LSSharedFileListCopySnapshot(loginItems, &seed); - - for (id item in (__bridge NSArray *)loginItemsArray) - { - LSSharedFileListItemRef loginItem = (__bridge LSSharedFileListItemRef)item; - CFURLRef itemUrl; - - if (LSSharedFileListItemResolve(loginItem, 0, &itemUrl, NULL) == noErr) - { - if (CFEqual(itemUrl, url)) - { - return YES; - } - } - else - { - NSLog(@"Error: LSSharedFileListItemResolve failed."); - } - } - } - else - { - NSLog(@"Warning: LSSharedFileListCreate failed, could not get list of login items."); - } - - return NO; +- (BOOL)isLoginItem { + LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, + kLSSharedFileListSessionLoginItems, + NULL); + + if (loginItems) { + UInt32 seed; + CFArrayRef loginItemsArray = LSSharedFileListCopySnapshot(loginItems, &seed); + + for (id item in (__bridge NSArray *)loginItemsArray) { + LSSharedFileListItemRef loginItem = (__bridge LSSharedFileListItemRef)item; + CFURLRef itemUrl; + + if (LSSharedFileListItemResolve(loginItem, 0, &itemUrl, NULL) == noErr) { + if (CFEqual(itemUrl, url)) { + CFRelease(loginItemsArray); + return YES; + } + } + else { + NSLog(@"Error: LSSharedFileListItemResolve failed."); + } + } + if (loginItemsArray) { + CFRelease(loginItemsArray); + } + } + else { + NSLog(@"Warning: LSSharedFileListCreate failed, could not get list of login items."); + } + + return NO; } -- (void)addLoginItem -{ - LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, - kLSSharedFileListSessionLoginItems, - NULL); - - if (!loginItems) - { - NSLog(@"Error: LSSharedFileListCreate failed, could not get list of login items."); - return; - } - - // If an item path has been specified as specific insertion point for the - // login item to add, then look for it. - if(!LSSharedFileListInsertItemURL(loginItems, - [self findInsertionPoint:loginItems], - NULL, - _iconRef, - url, - NULL, - NULL)) - { - NSLog(@"Error: LSSharedFileListInsertItemURL failed, could not create login item."); - } +- (void)addLoginItem { + LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, + kLSSharedFileListSessionLoginItems, + NULL); + + if (!loginItems) { + NSLog(@"Error: LSSharedFileListCreate failed, could not get list of login items."); + return; + } + + // If an item path has been specified as specific insertion point for the + // login item to add, then look for it. + if (!LSSharedFileListInsertItemURL(loginItems, + [self findInsertionPoint:loginItems], + NULL, + _iconRef, + url, + NULL, + NULL)) { + NSLog(@"Error: LSSharedFileListInsertItemURL failed, could not create login item."); + } } -- (LSSharedFileListItemRef)findInsertionPoint:(LSSharedFileListRef)loginItems -{ - if (itemBeforeInsertion) - { - return itemBeforeInsertion; - } - - // itemBeforePath - const LSSharedFileListItemRef found = [self findItem:loginItems withPath:itemBeforePath]; - - if (found) - { - return found; - } - - NSLog(@"Warning: Could not find item with specified path."); - - // If no item with the specified path has been found, then the last position - // is returned. - return kLSSharedFileListItemLast; +- (LSSharedFileListItemRef)findInsertionPoint:(LSSharedFileListRef)loginItems { + if (itemBeforeInsertion) { + return itemBeforeInsertion; + } + + // itemBeforePath + const LSSharedFileListItemRef found = [self findItem:loginItems withPath:itemBeforePath]; + + if (found) { + return found; + } + + NSLog(@"Warning: Could not find item with specified path."); + + // If no item with the specified path has been found, then the last position + // is returned. + return kLSSharedFileListItemLast; } - (LSSharedFileListItemRef)findItem:(LSSharedFileListRef)loginItems - withPath:(CFURLRef)path -{ - UInt32 seed; - CFArrayRef loginItemsArray = LSSharedFileListCopySnapshot(loginItems, &seed); - - for (id item in (__bridge NSArray *)loginItemsArray) - { - LSSharedFileListItemRef loginItem = (__bridge LSSharedFileListItemRef)item; - CFURLRef itemUrl; - - if (LSSharedFileListItemResolve(loginItem, 0, &itemUrl, NULL) == noErr) - { - if (CFEqual(itemUrl, path)) - { - return loginItem; - } - } - } - - return nil; + withPath:(CFURLRef)path { + UInt32 seed; + CFArrayRef loginItemsArray = LSSharedFileListCopySnapshot(loginItems, &seed); + + for (id item in (__bridge NSArray *)loginItemsArray) { + LSSharedFileListItemRef loginItem = (__bridge LSSharedFileListItemRef)item; + CFURLRef itemUrl; + + if (LSSharedFileListItemResolve(loginItem, 0, &itemUrl, NULL) == noErr) { + if (CFEqual(itemUrl, path)) { + CFRelease(loginItemsArray); + return loginItem; + } + } + } + if (loginItemsArray) { + CFRelease(loginItemsArray); + } + return nil; } -- (void)removeLoginItem -{ - LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, - kLSSharedFileListSessionLoginItems, - NULL); - if (loginItems) - { - BOOL removed = NO; - UInt32 seed; - CFArrayRef loginItemsArray = LSSharedFileListCopySnapshot(loginItems, &seed); - - for (id item in (__bridge NSArray *)loginItemsArray) - { - LSSharedFileListItemRef loginItem = (__bridge LSSharedFileListItemRef)item; - CFURLRef itemUrl; - - if (LSSharedFileListItemResolve(loginItem, 0, &itemUrl, NULL) == noErr) - { - if (CFEqual(itemUrl, url)) - { - if (LSSharedFileListItemRemove(loginItems, loginItem) == noErr) - { - removed = YES; - break; - } - else - { - NSLog(@"Error: Unknown error while removing login item."); - } - } - } - else - { - NSLog(@"Warning: LSSharedFileListItemResolve failed, could not resolve item."); - } - } - - if (!removed) - { - NSLog(@"Error: could not find login item to remove."); - } - } - else - { - NSLog(@"Warning: could not get list of login items."); - } +- (void)removeLoginItem { + LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, + kLSSharedFileListSessionLoginItems, + NULL); + if (loginItems) { + BOOL removed = NO; + UInt32 seed; + CFArrayRef loginItemsArray = LSSharedFileListCopySnapshot(loginItems, &seed); + + for (id item in (__bridge NSArray *)loginItemsArray) { + LSSharedFileListItemRef loginItem = (__bridge LSSharedFileListItemRef)item; + CFURLRef itemUrl; + + if (LSSharedFileListItemResolve(loginItem, 0, &itemUrl, NULL) == noErr) { + if (CFEqual(itemUrl, url)) { + if (LSSharedFileListItemRemove(loginItems, loginItem) == noErr) { + removed = YES; + break; + } + else { + NSLog(@"Error: Unknown error while removing login item."); + } + } + } + else { + NSLog(@"Warning: LSSharedFileListItemResolve failed, could not resolve item."); + } + } + if (loginItemsArray) { + CFRelease(loginItemsArray); + } + if (!removed) { + NSLog(@"Error: could not find login item to remove."); + } + } + else { + NSLog(@"Warning: could not get list of login items."); + } } -- (void)addAfterLast -{ - itemBeforeInsertion = kLSSharedFileListItemLast; - itemBeforePath = nil; +- (void)addAfterLast { + itemBeforeInsertion = kLSSharedFileListItemLast; + itemBeforePath = nil; } -- (void)addAfterFirst -{ - itemBeforeInsertion = kLSSharedFileListItemBeforeFirst; - itemBeforePath = nil; +- (void)addAfterFirst { + itemBeforeInsertion = kLSSharedFileListItemBeforeFirst; + itemBeforePath = nil; } -- (void)addAfterItemWithPath:(NSString *)path -{ - if (!path) - { - NSException* nullException = [NSException - exceptionWithName:@"NullPointerException" - reason:@"Path cannot be null." - userInfo:nil]; - @throw nullException; - } - - itemBeforeInsertion = nil; - itemBeforePath = (CFURLRef)CFBridgingRetain([NSURL fileURLWithPath:path]); +- (void)addAfterItemWithPath:(NSString *)path { + if (!path) { + NSException *nullException = [NSException + exceptionWithName:@"NullPointerException" + reason:@"Path cannot be null." + userInfo:nil]; + @throw nullException; + } + + itemBeforeInsertion = nil; + itemBeforePath = (CFURLRef)CFBridgingRetain([NSURL fileURLWithPath:path]); } -- (void)addAfterBundle:(NSBundle *)bundle -{ - if (!bundle) - { - NSException* nullException = [NSException - exceptionWithName:@"NullPointerException" - reason:@"Bundle cannot be null." - userInfo:nil]; - @throw nullException; - } - - itemBeforeInsertion = nil; - itemBeforePath = (CFURLRef)CFBridgingRetain([NSURL fileURLWithPath:[bundle bundlePath]]); +- (void)addAfterBundle:(NSBundle *)bundle { + if (!bundle) { + NSException *nullException = [NSException + exceptionWithName:@"NullPointerException" + reason:@"Bundle cannot be null." + userInfo:nil]; + @throw nullException; + } + + itemBeforeInsertion = nil; + itemBeforePath = (CFURLRef)CFBridgingRetain([NSURL fileURLWithPath:[bundle bundlePath]]); } @end - diff --git a/PrefPane/MenuMetersPref.h b/PrefPane/MenuMetersPref.h index 5328fe96..411c03c3 100644 --- a/PrefPane/MenuMetersPref.h +++ b/PrefPane/MenuMetersPref.h @@ -1,154 +1,162 @@ // // MenuMetersPrefPane.h // -// MenuMeters pref panel +// MenuMeters pref panel // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -#import -#import -#import -#import -#import -#import -#import "MenuMeters.h" -#import "MenuMeterDefaults.h" -#import "MenuMeterWorkarounds.h" #import "MenuMeterCPU.h" +#import "MenuMeterDefaults.h" #import "MenuMeterDisk.h" #import "MenuMeterMem.h" #import "MenuMeterNet.h" #import "MenuMeterPowerMate.h" +#import "MenuMeterWorkarounds.h" +#import "MenuMeters.h" +#import +#import +#import +#import +#import +#import #ifdef SPARKLE #import #endif - -@interface MenuMetersPref : -NSWindowController -{ +@interface MenuMetersPref : NSWindowController { // Our preferences - MenuMeterDefaults *ourPrefs; + MenuMeterDefaults *ourPrefs; // System config framework hooks - SCDynamicStoreRef scSession; - CFRunLoopSourceRef scRunSource; + SCDynamicStoreRef scSession; + CFRunLoopSourceRef scRunSource; // Main controls - IBOutlet NSTabView *prefTabs; - __unsafe_unretained IBOutlet NSTextView *aboutView; - // CPU pane controlsaverage - IBOutlet NSButton *cpuMeterToggle; - __weak IBOutlet NSButton *cpuPercentage; - __weak IBOutlet NSButton *cpuGraph; - __weak IBOutlet NSButton *cpuThermometer; - __weak IBOutlet NSButton *cpuHorizontalThermometer; - - IBOutlet NSButton *cpuTemperatureToggle; - __weak IBOutlet NSPopUpButton *cpuTemperatureUnit; - IBOutlet NSTextField *cpuIntervalDisplay; - IBOutlet NSSlider *cpuInterval; - IBOutlet NSPopUpButton *cpuPercentMode; - IBOutlet NSTextField *cpuPercentModeLabel; - IBOutlet NSSlider *cpuMaxProcessCount; - IBOutlet NSTextField *cpuMaxProcessCountCountLabel; - IBOutlet NSSlider *cpuGraphWidth; - IBOutlet NSTextField *cpuGraphWidthLabel; - IBOutlet NSSlider *cpuHorizontalRows; - IBOutlet NSTextField *cpuHorizontalRowsLabel; - IBOutlet NSSlider *cpuMenuWidth; - IBOutlet NSTextField *cpuMenuWidthLabel; - IBOutlet NSPopUpButton *cpuMultipleCPU; - IBOutlet NSButton *cpuPowerMate; - IBOutlet NSPopUpButton *cpuPowerMateMode; - IBOutlet NSColorWell *cpuUserColor; - IBOutlet NSColorWell *cpuTemperatureColor; - IBOutlet NSPopUpButton* cpuTemperatureSensor; - IBOutlet NSTextField *cpuUserColorLabel; - IBOutlet NSColorWell *cpuSystemColor; - IBOutlet NSTextField *cpuSystemColorLabel; + IBOutlet NSTabView *prefTabs; + __unsafe_unretained IBOutlet NSTextView *aboutView; + // CPU pane controlsaverage + IBOutlet NSButton *cpuMeterToggle; + __weak IBOutlet NSButton *cpuPercentage; + __weak IBOutlet NSButton *cpuGraph; + __weak IBOutlet NSButton *cpuThermometer; + __weak IBOutlet NSButton *cpuHorizontalThermometer; + + IBOutlet NSButton *cpuTemperatureToggle; + __weak IBOutlet NSPopUpButton *cpuTemperatureUnit; + IBOutlet NSTextField *cpuIntervalDisplay; + IBOutlet NSSlider *cpuInterval; + IBOutlet NSPopUpButton *cpuPercentMode; + IBOutlet NSTextField *cpuPercentModeLabel; + IBOutlet NSSlider *cpuMaxProcessCount; + IBOutlet NSTextField *cpuMaxProcessCountCountLabel; + IBOutlet NSSlider *cpuGraphWidth; + IBOutlet NSTextField *cpuGraphWidthLabel; + IBOutlet NSSlider *cpuHorizontalRows; + IBOutlet NSTextField *cpuHorizontalRowsLabel; + IBOutlet NSSlider *cpuMenuWidth; + IBOutlet NSTextField *cpuMenuWidthLabel; + IBOutlet NSPopUpButton *cpuMultipleCPU; + IBOutlet NSButton *cpuPowerMate; + IBOutlet NSPopUpButton *cpuPowerMateMode; + IBOutlet NSColorWell *cpuUserColor; + IBOutlet NSColorWell *cpuTemperatureColor; + IBOutlet NSPopUpButton *cpuTemperatureSensor; + IBOutlet NSTextField *cpuUserColorLabel; + IBOutlet NSColorWell *cpuSystemColor; + IBOutlet NSTextField *cpuSystemColorLabel; // Disk pane controls - IBOutlet NSButton *diskMeterToggle; - IBOutlet NSPopUpButton *diskImageSet; - IBOutlet NSTextField *diskIntervalDisplay; - IBOutlet NSSlider *diskInterval; - IBOutlet NSPopUpButton *diskSelectMode; + IBOutlet NSButton *diskMeterToggle; + IBOutlet NSPopUpButton *diskImageSet; + IBOutlet NSTextField *diskIntervalDisplay; + IBOutlet NSSlider *diskInterval; + IBOutlet NSPopUpButton *diskSelectMode; // Mem pane controls - IBOutlet NSButton *memMeterToggle; - IBOutlet NSPopUpButton *memDisplayMode; - IBOutlet NSTextField *memIntervalDisplay; - IBOutlet NSSlider *memInterval; - IBOutlet NSButton *memFreeUsedLabeling; - IBOutlet NSButton *memPageIndicator; - IBOutlet NSSlider *memGraphWidth; - IBOutlet NSTextField *memGraphWidthLabel; - IBOutlet NSColorWell *memActiveColor; - IBOutlet NSColorWell *memInactiveColor; - IBOutlet NSColorWell *memWiredColor; - IBOutlet NSColorWell *memCompressedColor; - IBOutlet NSColorWell *memFreeColor; - IBOutlet NSColorWell *memUsedColor; - IBOutlet NSColorWell *memPageinColor; - IBOutlet NSTextField *memPageinColorLabel; - IBOutlet NSColorWell *memPageoutColor; - IBOutlet NSTextField *memPageoutColorLabel; - IBOutlet NSButton *memPressureMode; + IBOutlet NSButton *memMeterToggle; + IBOutlet NSPopUpButton *memDisplayMode; + IBOutlet NSTextField *memIntervalDisplay; + IBOutlet NSSlider *memInterval; + IBOutlet NSButton *memFreeUsedLabeling; + IBOutlet NSButton *memPageIndicator; + IBOutlet NSSlider *memGraphWidth; + IBOutlet NSTextField *memGraphWidthLabel; + IBOutlet NSColorWell *memActiveColor; + IBOutlet NSColorWell *memInactiveColor; + IBOutlet NSColorWell *memWiredColor; + IBOutlet NSColorWell *memCompressedColor; + IBOutlet NSColorWell *memFreeColor; + IBOutlet NSColorWell *memUsedColor; + IBOutlet NSColorWell *memPageinColor; + IBOutlet NSTextField *memPageinColorLabel; + IBOutlet NSColorWell *memPageoutColor; + IBOutlet NSTextField *memPageoutColorLabel; + IBOutlet NSButton *memPressureMode; // Net pane controls - IBOutlet NSButton *netMeterToggle; - IBOutlet NSPopUpButton *netDisplayMode; - IBOutlet NSPopUpButton *netDisplayOrientation; - IBOutlet NSPopUpButton *netPreferInterface; - IBOutlet NSPopUpButton *netScaleMode; - IBOutlet NSTextField *netScaleModeLabel; - IBOutlet NSPopUpButton *netScaleCalc; - IBOutlet NSTextField *netScaleCalcLabel; - IBOutlet NSTextField *netIntervalDisplay; - IBOutlet NSSlider *netInterval; - IBOutlet NSButton *netThroughputLabeling; - IBOutlet NSButton *netThroughput1KBound; - IBOutlet NSButton *netThroughputBits; - IBOutlet NSPopUpButton *netGraphStyle; - IBOutlet NSTextField *netGraphStyleLabel; - IBOutlet NSSlider *netGraphWidth; - IBOutlet NSTextField *netGraphWidthLabel; - IBOutlet NSColorWell *netTxColor; - IBOutlet NSColorWell *netRxColor; - IBOutlet NSColorWell *netInactiveColor; - __weak IBOutlet NSPopUpButton *updateIntervalButton; - IBOutlet NSView *sparkleUIContainer; + IBOutlet NSButton *netMeterToggle; + IBOutlet NSPopUpButton *netDisplayMode; + IBOutlet NSPopUpButton *netDisplayOrientation; + IBOutlet NSPopUpButton *netPreferInterface; + IBOutlet NSPopUpButton *netScaleMode; + IBOutlet NSTextField *netScaleModeLabel; + IBOutlet NSPopUpButton *netScaleCalc; + IBOutlet NSTextField *netScaleCalcLabel; + IBOutlet NSTextField *netIntervalDisplay; + IBOutlet NSSlider *netInterval; + IBOutlet NSButton *netThroughputLabeling; + IBOutlet NSButton *netThroughput1KBound; + IBOutlet NSButton *netThroughputBits; + IBOutlet NSPopUpButton *netGraphStyle; + IBOutlet NSTextField *netGraphStyleLabel; + IBOutlet NSSlider *netGraphWidth; + IBOutlet NSTextField *netGraphWidthLabel; + IBOutlet NSColorWell *netTxColor; + IBOutlet NSColorWell *netRxColor; + IBOutlet NSColorWell *netInactiveColor; + __weak IBOutlet NSPopUpButton *updateIntervalButton; + IBOutlet NSView *sparkleUIContainer; } // MenuMetersPref // Pref pane standard methods + - (void)mainViewDidLoad; + - (void)willSelect; + - (void)didUnselect; #ifdef SPARKLE --(instancetype)initWithAboutFileName:(NSString*)about andUpdater:(SUUpdater*)updater_; + +- (instancetype)initWithAboutFileName:(NSString *)about andUpdater:(SUUpdater *)updater_; #else --(instancetype)initWithAboutFileName:(NSString*)about; + +- (instancetype)initWithAboutFileName:(NSString *)about; #endif // IB Targets --(IBAction)openAbout:(id)sender; + +- (IBAction)openAbout:(id)sender; + - (IBAction)liveUpdateInterval:(id)sender; + - (IBAction)cpuPrefChange:(id)sender; + - (IBAction)diskPrefChange:(id)sender; + - (IBAction)memPrefChange:(id)sender; + - (IBAction)netPrefChange:(id)sender; @end diff --git a/PrefPane/MenuMetersPref.m b/PrefPane/MenuMetersPref.m index 3d2823b0..9d18f924 100644 --- a/PrefPane/MenuMetersPref.m +++ b/PrefPane/MenuMetersPref.m @@ -1,24 +1,24 @@ // // MenuMetersPrefPane.m // -// MenuMeters pref panel +// MenuMeters pref panel // -// Copyright (c) 2002-2014 Alex Harper +// Copyright (c) 2002-2014 Alex Harper // -// This file is part of MenuMeters. +// This file is part of MenuMeters. // -// MenuMeters is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as +// MenuMeters is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // -// MenuMeters is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// MenuMeters is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with MenuMeters; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU General Public License +// along with MenuMeters; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #import "MenuMetersPref.h" @@ -30,36 +30,47 @@ #import "TemperatureReader.h" /////////////////////////////////////////////////////////////// // -// Private methods and constants +// Private methods and constants // /////////////////////////////////////////////////////////////// @interface MenuMetersPref (PrivateMethods) // Notifications + - (void)menuExtraUnloaded:(NSNotification *)notification; + - (void)menuExtraChangedPrefs:(NSNotification *)notification; // Menu extra manipulations + - (void)loadExtraAtURL:(NSURL *)extraURL withID:(NSString *)bundleID; + - (BOOL)isExtraWithBundleIDLoaded:(NSString *)bundleID; + - (void)removeExtraWithBundleID:(NSString *)bundleID; + - (void)showMenuExtraErrorSheet; // Net configuration update + - (void)updateNetInterfaceMenu; // CPU info + - (BOOL)isMultiProcessor; // System config framework + - (void)connectSystemConfig; + - (void)disconnectSystemConfig; + - (NSDictionary *)sysconfigValueForKey:(NSString *)key; @end // MenuCracker -#define kMenuCrackerURL [NSURL fileURLWithPath:[[self bundle] pathForResource:@"MenuCracker" ofType:@"menu" inDirectory:@""]] +#define kMenuCrackerURL [NSURL fileURLWithPath:[[self bundle] pathForResource:@"MenuCracker" ofType:@"menu" inDirectory:@""]] // Paths to the menu extras #ifdef ELCAPITAN @@ -68,15 +79,15 @@ - (NSDictionary *)sysconfigValueForKey:(NSString *)key; #define kMemMenuURL nil #define kNetMenuURL nil #else -#define kCPUMenuURL [NSURL fileURLWithPath:[[self bundle] pathForResource:@"MenuMeterCPU" ofType:@"menu" inDirectory:@""]] -#define kDiskMenuURL [NSURL fileURLWithPath:[[self bundle] pathForResource:@"MenuMeterDisk" ofType:@"menu" inDirectory:@""]] -#define kMemMenuURL [NSURL fileURLWithPath:[[self bundle] pathForResource:@"MenuMeterMem" ofType:@"menu" inDirectory:@""]] -#define kNetMenuURL [NSURL fileURLWithPath:[[self bundle] pathForResource:@"MenuMeterNet" ofType:@"menu" inDirectory:@""]] +#define kCPUMenuURL [NSURL fileURLWithPath:[[self bundle] pathForResource:@"MenuMeterCPU" ofType:@"menu" inDirectory:@""]] +#define kDiskMenuURL [NSURL fileURLWithPath:[[self bundle] pathForResource:@"MenuMeterDisk" ofType:@"menu" inDirectory:@""]] +#define kMemMenuURL [NSURL fileURLWithPath:[[self bundle] pathForResource:@"MenuMeterMem" ofType:@"menu" inDirectory:@""]] +#define kNetMenuURL [NSURL fileURLWithPath:[[self bundle] pathForResource:@"MenuMeterNet" ofType:@"menu" inDirectory:@""]] #endif // How long to wait for Extras to add once CoreMenuExtraAddMenuExtra returns? -#define kWaitForExtraLoadMicroSec 10000000 -#define kWaitForExtraLoadStepMicroSec 250000 +#define kWaitForExtraLoadMicroSec 10000000 +#define kWaitForExtraLoadStepMicroSec 250000 // Mem panel hidden tabs for color controls enum { @@ -86,177 +97,185 @@ - (NSDictionary *)sysconfigValueForKey:(NSString *)key; /////////////////////////////////////////////////////////////// // -// SystemConfiguration notification callbacks +// SystemConfiguration notification callbacks // /////////////////////////////////////////////////////////////// static void scChangeCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) { - if (info) [(__bridge MenuMetersPref *)info updateNetInterfaceMenu]; + if (info) + [(__bridge MenuMetersPref *)info updateNetInterfaceMenu]; } // scChangeCallback - -@implementation MenuMetersPref -{ - IBOutlet NSWindow* _window; +@implementation MenuMetersPref { + IBOutlet NSWindow *_window; #ifdef SPARKLE - SUUpdater*updater; + SUUpdater *updater; #endif } --(IBAction)showAlertConcerningSystemEventsEtc:(id)sender -{ - NSButton*b=sender; - if([b state]==NSOnState){ - NSAlert*alert=[[NSAlert alloc] init]; - alert.messageText=@"Using this feature for the first time will bring up two alerts by the system"; - [alert addButtonWithTitle:@"OK"]; - alert.informativeText=@"This feature uses AppleScript and System Events to simulate a click to switch to a specific pane of the Activity Monitor. This requires 1. one confirmation dialog to allow MenuMeters to use AppleScript, and 2. a trip to the Security & Privacy pane of the System Preferences to allow MenuMeters to use Accesibility features."; - [alert runModal]; - } + +- (IBAction)showAlertConcerningSystemEventsEtc:(id)sender { + NSButton *b = sender; + if ([b state] == NSOnState) { + NSAlert *alert = [[NSAlert alloc] init]; + alert.messageText = @"Using this feature for the first time will bring up two alerts by the system"; + [alert addButtonWithTitle:@"OK"]; + alert.informativeText = @"This feature uses AppleScript and System Events to simulate a click to switch to a specific pane of the Activity Monitor. This requires 1. one confirmation dialog to allow MenuMeters to use AppleScript, and 2. a trip to the Security & Privacy pane of the System Preferences to allow MenuMeters to use Accesibility features."; + [alert runModal]; + } } --(IBAction)openAbout:(id)sender -{ - [prefTabs selectTabViewItemAtIndex:4]; - [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - [NSApp activateIgnoringOtherApps:YES]; - [self.window makeKeyAndOrderFront:self]; + +- (IBAction)openAbout:(id)sender { + [prefTabs selectTabViewItemAtIndex:4]; + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + [NSApp activateIgnoringOtherApps:YES]; + [self.window makeKeyAndOrderFront:self]; } --(void)openPrefPane:(NSNotification*)notification -{ - id obj=notification.object; - if([obj isKindOfClass:[MenuMeterCPUExtra class]]){ - [prefTabs selectTabViewItemAtIndex:0]; - } - if([obj isKindOfClass:[MenuMeterDiskExtra class]]){ - [prefTabs selectTabViewItemAtIndex:1]; - } - if([obj isKindOfClass:[MenuMeterMemExtra class]]){ - [prefTabs selectTabViewItemAtIndex:2]; - } - if([obj isKindOfClass:[MenuMeterNetExtra class]]){ - [prefTabs selectTabViewItemAtIndex:3]; - } - [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - [NSApp activateIgnoringOtherApps:YES]; - [self.window makeKeyAndOrderFront:self]; + +- (void)openPrefPane:(NSNotification *)notification { + id obj = notification.object; + if ([obj isKindOfClass:[MenuMeterCPUExtra class]]) { + [prefTabs selectTabViewItemAtIndex:0]; + } + if ([obj isKindOfClass:[MenuMeterDiskExtra class]]) { + [prefTabs selectTabViewItemAtIndex:1]; + } + if ([obj isKindOfClass:[MenuMeterMemExtra class]]) { + [prefTabs selectTabViewItemAtIndex:2]; + } + if ([obj isKindOfClass:[MenuMeterNetExtra class]]) { + [prefTabs selectTabViewItemAtIndex:3]; + } + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + [NSApp activateIgnoringOtherApps:YES]; + [self.window makeKeyAndOrderFront:self]; } --(BOOL)noMenuMeterLoaded -{ - return ![self isExtraWithBundleIDLoaded:kCPUMenuBundleID] && - ![self isExtraWithBundleIDLoaded:kDiskMenuBundleID] && - ![self isExtraWithBundleIDLoaded:kMemMenuBundleID] && - ![self isExtraWithBundleIDLoaded:kNetMenuBundleID]; + +- (BOOL)noMenuMeterLoaded { + return ![self isExtraWithBundleIDLoaded:kCPUMenuBundleID] && + ![self isExtraWithBundleIDLoaded:kDiskMenuBundleID] && + ![self isExtraWithBundleIDLoaded:kMemMenuBundleID] && + ![self isExtraWithBundleIDLoaded:kNetMenuBundleID]; } --(void)setupAboutTab:(NSString*)about -{ - NSString*pathToRTF=[[NSBundle mainBundle] pathForResource:about ofType:@"rtf"]; - NSMutableAttributedString*x=[[NSMutableAttributedString alloc] initWithURL:[NSURL fileURLWithPath:pathToRTF] options:@{} documentAttributes:nil error:nil]; - [x addAttribute:NSForegroundColorAttributeName value:[NSColor textColor] range:NSMakeRange(0, x.length)]; - [aboutView.textStorage appendAttributedString:x]; + +- (void)setupAboutTab:(NSString *)about { + NSString *pathToRTF = [[NSBundle mainBundle] pathForResource:about ofType:@"rtf"]; + NSMutableAttributedString *x = [[NSMutableAttributedString alloc] initWithURL:[NSURL fileURLWithPath:pathToRTF] options:@{} documentAttributes:nil error:nil]; + [x addAttribute:NSForegroundColorAttributeName value:[NSColor textColor] range:NSMakeRange(0, x.length)]; + [aboutView.textStorage appendAttributedString:x]; + aboutView.textContainerInset = NSMakeSize(12, 8); } --(void)initCommon:(NSString*)about -{ - [self loadWindow]; - self.window=_window; - [self.window setDelegate:self]; - [self mainViewDidLoad]; - [self willSelect]; - [self setupAboutTab:about]; - if([self noMenuMeterLoaded]){ - [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - [self.window makeKeyAndOrderFront:self]; - } - [self setupSparkleUI]; + +- (void)initCommon:(NSString *)about { + [self loadWindow]; + self.window = _window; + [self.window setDelegate:self]; + [self mainViewDidLoad]; + [self willSelect]; + [self setupAboutTab:about]; + if ([self noMenuMeterLoaded]) { + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + [self.window makeKeyAndOrderFront:self]; + } + [self setupSparkleUI]; } #ifdef SPARKLE --(instancetype)initWithAboutFileName:(NSString*)about andUpdater:(SUUpdater*)updater_ -{ - self=[super initWithWindowNibName:@"MenuMetersPref"]; - updater=updater_; - [self initCommon:about]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(openPrefPane:) name:@"openPref" object:nil]; - return self; + +- (instancetype)initWithAboutFileName:(NSString *)about andUpdater:(SUUpdater *)updater_ { + self = [super initWithWindowNibName:@"MenuMetersPref"]; + updater = updater_; + [self initCommon:about]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(openPrefPane:) name:@"openPref" object:nil]; + return self; } #else --(instancetype)initWithAboutFileName:(NSString*)about -{ - self=[super initWithWindowNibName:@"MenuMetersPref"]; - [self initCommon:about]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(openPrefPane:) name:@"openPref" object:nil]; - return self; + +- (instancetype)initWithAboutFileName:(NSString *)about { + self = [super initWithWindowNibName:@"MenuMetersPref"]; + [self initCommon:about]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(openPrefPane:) name:@"openPref" object:nil]; + return self; } #endif --(NSView*)mainView{ - return self.window.contentView; + +- (NSView *)mainView { + return self.window.contentView; } --(NSBundle*)bundle{ - return [NSBundle mainBundle]; + +- (NSBundle *)bundle { + return [NSBundle mainBundle]; } --(void)windowWillClose:(NSNotification *)notification -{ - if(![self noMenuMeterLoaded]){ - [NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory]; - } + +- (void)windowWillClose:(NSNotification *)notification { + if (![self noMenuMeterLoaded]) { + [NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory]; + } } --(void)setupSparkleUI -{ - // This is hacky, but if we're a Sparkle build this sets up the updater UI bits, - // and if we're not, just hide them + +- (void)setupSparkleUI { + // This is hacky, but if we're a Sparkle build this sets up the updater UI bits, + // and if we're not, just hide them #ifdef SPARKLE - if(updater.automaticallyChecksForUpdates){ - NSTimeInterval updateInterval=updater.updateCheckInterval; - if(updateInterval<3600*24+1){ - [updateIntervalButton selectItemAtIndex:1]; - }else if(updateInterval<7*3600*24+1){ - [updateIntervalButton selectItemAtIndex:2]; - }else if(updateInterval<30*3600*24+1){ - [updateIntervalButton selectItemAtIndex:3]; - }else{ - [updateIntervalButton selectItemAtIndex:1]; - } - }else{ - [updateIntervalButton selectItemAtIndex:0]; - } + if (updater.automaticallyChecksForUpdates) { + NSTimeInterval updateInterval = updater.updateCheckInterval; + if (updateInterval < 3600 * 24 + 1) { + [updateIntervalButton selectItemAtIndex:1]; + } + else if (updateInterval < 7 * 3600 * 24 + 1) { + [updateIntervalButton selectItemAtIndex:2]; + } + else if (updateInterval < 30 * 3600 * 24 + 1) { + [updateIntervalButton selectItemAtIndex:3]; + } + else { + [updateIntervalButton selectItemAtIndex:1]; + } + } + else { + [updateIntervalButton selectItemAtIndex:0]; + } #else - sparkleUIContainer.hidden = YES; + sparkleUIContainer.hidden = YES; #endif } --(IBAction)updateInterval:(id)sender -{ + +- (IBAction)updateInterval:(id)sender { #ifdef SPARKLE - NSPopUpButton*button=sender; - NSInteger intervalInDays=1; - switch(button.indexOfSelectedItem){ - case 0: - intervalInDays=-1; - break; - case 1: - intervalInDays=1; - break; - case 2: - intervalInDays=7; - break; - case 3: - intervalInDays=30; - break; - default: - intervalInDays=1; - break; - } - if(intervalInDays<=0){ - [updater setAutomaticallyChecksForUpdates:NO]; - }else{ - [updater setAutomaticallyChecksForUpdates:YES]; - [updater setUpdateCheckInterval:intervalInDays*3600*24]; - } + NSPopUpButton *button = sender; + NSInteger intervalInDays = 1; + switch (button.indexOfSelectedItem) { + case 0: + intervalInDays = -1; + break; + case 1: + intervalInDays = 1; + break; + case 2: + intervalInDays = 7; + break; + case 3: + intervalInDays = 30; + break; + default: + intervalInDays = 1; + break; + } + if (intervalInDays <= 0) { + [updater setAutomaticallyChecksForUpdates:NO]; + } + else { + [updater setAutomaticallyChecksForUpdates:YES]; + [updater setUpdateCheckInterval:intervalInDays * 3600 * 24]; + } #endif } /////////////////////////////////////////////////////////////// // -// Pref pane standard methods +// Pref pane standard methods // /////////////////////////////////////////////////////////////// + - (void)mainViewDidLoad { // On first load switch to the first tab [prefTabs selectFirstTabViewItem:self]; @@ -265,17 +284,15 @@ - (void)mainViewDidLoad { NSEnumerator *diskImageSetEnum = [kDiskImageSets objectEnumerator]; [diskImageSet removeAllItems]; NSString *imageSetName = nil; + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; while ((imageSetName = [diskImageSetEnum nextObject])) { - [diskImageSet addItemWithTitle:[[NSBundle bundleForClass:[self class]] - localizedStringForKey:imageSetName - value:nil - table:@"DiskImageSet"]]; + [diskImageSet addItemWithTitle:[bundle localizedStringForKey:imageSetName value:nil table:@"DiskImageSet"]]; } // Set up a NSFormatter for use printing timers NSNumberFormatter *intervalFormatter = [[NSNumberFormatter alloc] init]; [intervalFormatter setLocalizesFormat:YES]; - [intervalFormatter setFormat:@"###0.0"]; + [intervalFormatter setFormat:@"###0.0\u2009s"]; // Go through an archive/unarchive cycle to work around a bug on pre-10.2.2 systems // see http://cocoa.mamasam.com/COCOADEV/2001/12/2/21029.php intervalFormatter = [NSUnarchiver unarchiveObjectWithData:[NSArchiver archivedDataWithRootObject:intervalFormatter]]; @@ -285,72 +302,71 @@ - (void)mainViewDidLoad { [netIntervalDisplay setFormatter:intervalFormatter]; // Configure the scale menu to contain images and enough space - [[netScaleCalc itemAtIndex:kNetScaleCalcLinear] setImage:[[NSImage alloc] initWithContentsOfFile:[[self bundle] - pathForResource:@"LinearScale" ofType:@"tiff"]]]; - [[netScaleCalc itemAtIndex:kNetScaleCalcLinear] setTitle:[NSString stringWithFormat:@" %@", - [[netScaleCalc itemAtIndex:kNetScaleCalcLinear] title]]]; - [[netScaleCalc itemAtIndex:kNetScaleCalcSquareRoot] setImage:[[NSImage alloc] initWithContentsOfFile:[[self bundle] - pathForResource:@"SquareRootScale" ofType:@"tiff"]]]; - [[netScaleCalc itemAtIndex:kNetScaleCalcSquareRoot] setTitle:[NSString stringWithFormat:@" %@", - [[netScaleCalc itemAtIndex:kNetScaleCalcSquareRoot] title]]]; - [[netScaleCalc itemAtIndex:kNetScaleCalcCubeRoot] setImage:[[NSImage alloc] initWithContentsOfFile:[[self bundle] - pathForResource:@"CubeRootScale" ofType:@"tiff"]]]; - [[netScaleCalc itemAtIndex:kNetScaleCalcCubeRoot] setTitle:[NSString stringWithFormat:@" %@", - [[netScaleCalc itemAtIndex:kNetScaleCalcCubeRoot] title]]]; - [[netScaleCalc itemAtIndex:kNetScaleCalcLog] setImage:[[NSImage alloc] initWithContentsOfFile:[[self bundle] - pathForResource:@"LogScale" ofType:@"tiff"]]]; - [[netScaleCalc itemAtIndex:kNetScaleCalcLog] setTitle:[NSString stringWithFormat:@" %@", - [[netScaleCalc itemAtIndex:kNetScaleCalcLog] title]]]; - - { - NSString*oldAppPath=[@"~/Library/PreferencePanes/MenuMeters.prefPane/Contents/Resources/MenuMetersApp.app" stringByExpandingTildeInPath]; - EMCLoginItem*oldItem=[EMCLoginItem loginItemWithPath:oldAppPath]; - if(oldItem.isLoginItem){ - [oldItem removeLoginItem]; - } - } - { - NSString*oldAppPath=@"/Library/PreferencePanes/MenuMeters.prefPane/Contents/Resources/MenuMetersApp.app"; - EMCLoginItem*oldItem=[EMCLoginItem loginItemWithPath:oldAppPath]; - if(oldItem.isLoginItem){ - [oldItem removeLoginItem]; - } - } - system("killall MenuMetersApp"); - { - EMCLoginItem*thisItem=[EMCLoginItem loginItemWithBundle:[NSBundle mainBundle]]; - if(!thisItem.isLoginItem){ - [thisItem addLoginItem]; - } - } + NSMenuItem *item; + item = [netScaleCalc itemAtIndex:kNetScaleCalcLinear]; + item.image = [bundle imageForResource:@"LinearScale"]; + item.title = [@" %@" stringByAppendingString:item.title]; + + item = [netScaleCalc itemAtIndex:kNetScaleCalcSquareRoot]; + item.image = [bundle imageForResource:@"SquareRootScale"]; + item.title = [@" %@" stringByAppendingString:item.title]; + + item = [netScaleCalc itemAtIndex:kNetScaleCalcCubeRoot]; + item.image = [bundle imageForResource:@"CubeRootScale"]; + item.title = [@" %@" stringByAppendingString:item.title]; + + item = [netScaleCalc itemAtIndex:kNetScaleCalcLog]; + item.image = [bundle imageForResource:@"LogScale"]; + item.title = [@" %@" stringByAppendingString:item.title]; + { + NSString *oldAppPath = [@"~/Library/PreferencePanes/MenuMeters.prefPane/Contents/Resources/MenuMetersApp.app" stringByExpandingTildeInPath]; + EMCLoginItem *oldItem = [EMCLoginItem loginItemWithPath:oldAppPath]; + if (oldItem.isLoginItem) { + [oldItem removeLoginItem]; + } + } + { + NSString *oldAppPath = @"/Library/PreferencePanes/MenuMeters.prefPane/Contents/Resources/MenuMetersApp.app"; + EMCLoginItem *oldItem = [EMCLoginItem loginItemWithPath:oldAppPath]; + if (oldItem.isLoginItem) { + [oldItem removeLoginItem]; + } + } + system("killall MenuMetersApp"); + { + EMCLoginItem *thisItem = [EMCLoginItem loginItemWithBundle:bundle]; + if (!thisItem.isLoginItem) { + [thisItem addLoginItem]; + } + } } // mainViewDidLoad -- (void)updateTemperatureSensors -{ - NSArray*sensorNames=[TemperatureReader sensorNames]; - if(!sensorNames){ - cpuTemperatureSensor.enabled=NO; - return; - } - NSMenu*menu=[cpuTemperatureSensor menu]; - for(NSString*name in sensorNames){ - NSString*displayName=[TemperatureReader displayNameForSensor:name]; - NSMenuItem*item=[menu addItemWithTitle:displayName action:nil keyEquivalent:@""]; - item.toolTip=name; - } - NSString*sensor=[ourPrefs cpuTemperatureSensor]; - if([sensor isEqualTo:kCPUTemperatureSensorDefault]){ - sensor=[TemperatureReader defaultSensor]; - } - NSMenuItem*item=[menu itemWithTitle:[TemperatureReader displayNameForSensor:sensor]]; - if(!item){ - // This means that it is the first launch after migrating to a new Mac with a different set of sensors. - [ourPrefs saveCpuTemperatureSensor:kCPUTemperatureSensorDefault]; - sensor=[TemperatureReader defaultSensor]; - item=[menu itemWithTitle:[TemperatureReader displayNameForSensor:sensor]]; - } - [cpuTemperatureSensor selectItem:item]; +- (void)updateTemperatureSensors { + NSArray *sensorNames = [TemperatureReader sensorNames]; + if (!sensorNames) { + cpuTemperatureSensor.enabled = NO; + return; + } + NSMenu *menu = [cpuTemperatureSensor menu]; + for (NSString *name in sensorNames) { + NSString *displayName = [TemperatureReader displayNameForSensor:name]; + NSMenuItem *item = [menu addItemWithTitle:displayName action:nil keyEquivalent:@""]; + item.toolTip = name; + } + NSString *sensor = [ourPrefs cpuTemperatureSensor]; + if ([sensor isEqualTo:kCPUTemperatureSensorDefault]) { + sensor = [TemperatureReader defaultSensor]; + } + NSMenuItem *item = [menu itemWithTitle:[TemperatureReader displayNameForSensor:sensor]]; + if (!item) { + // This means that it is the first launch after migrating to a new Mac with a different set of sensors. + [ourPrefs saveCpuTemperatureSensor:kCPUTemperatureSensorDefault]; + sensor = [TemperatureReader defaultSensor]; + item = [menu itemWithTitle:[TemperatureReader displayNameForSensor:sensor]]; + } + [cpuTemperatureSensor selectItem:item]; } + - (void)willSelect { // Reread prefs on each load @@ -360,7 +376,8 @@ - (void)willSelect { if ([MenuMeterPowerMate powermateAttached]) { [cpuPowerMate setEnabled:YES]; [cpuPowerMateMode setEnabled:YES]; - } else { + } + else { [cpuPowerMate setEnabled:NO]; [cpuPowerMateMode setEnabled:NO]; } @@ -376,22 +393,22 @@ - (void)willSelect { // Build the preferred interface menu and select (this actually updates the net prefs too) [self updateNetInterfaceMenu]; - - [self updateTemperatureSensors]; + + [self updateTemperatureSensors]; // Reset the controls to match the prefs [self menuExtraChangedPrefs:nil]; // Register for pref change notifications from the extras [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(menuExtraChangedPrefs:) - name:kPrefPaneBundleID - object:kPrefChangeNotification]; + selector:@selector(menuExtraChangedPrefs:) + name:kPrefPaneBundleID + object:kPrefChangeNotification]; // Register for notifications from the extras when they unload [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(menuExtraUnloaded:) - name:@"menuExtraUnloaded" - object:nil]; + selector:@selector(menuExtraUnloaded:) + name:@"menuExtraUnloaded" + object:nil]; } // willSelect - (void)didUnselect { @@ -409,7 +426,7 @@ - (void)didUnselect { /////////////////////////////////////////////////////////////// // -// Notifications +// Notifications // /////////////////////////////////////////////////////////////// @@ -419,21 +436,23 @@ - (void)menuExtraUnloaded:(NSNotification *)notification { if (bundleID) { if ([bundleID isEqualToString:kCPUMenuBundleID]) { [cpuMeterToggle setState:NSOffState]; - } else if ([bundleID isEqualToString:kDiskMenuBundleID]) { + } + else if ([bundleID isEqualToString:kDiskMenuBundleID]) { [diskMeterToggle setState:NSOffState]; - } else if ([bundleID isEqualToString:kMemMenuBundleID]) { + } + else if ([bundleID isEqualToString:kMemMenuBundleID]) { [memMeterToggle setState:NSOffState]; - } else if ([bundleID isEqualToString:kNetMenuBundleID]) { + } + else if ([bundleID isEqualToString:kNetMenuBundleID]) { [netMeterToggle setState:NSOffState]; } } - [self removeExtraWithBundleID:bundleID]; + [self removeExtraWithBundleID:bundleID]; } // menuExtraUnloaded - (void)menuExtraChangedPrefs:(NSNotification *)notification { if (ourPrefs) { - [ourPrefs syncWithDisk]; [self cpuPrefChange:nil]; [self diskPrefChange:nil]; [self memPrefChange:nil]; @@ -444,7 +463,7 @@ - (void)menuExtraChangedPrefs:(NSNotification *)notification { /////////////////////////////////////////////////////////////// // -// IB Targets +// IB Targets // /////////////////////////////////////////////////////////////// @@ -456,12 +475,13 @@ - (IBAction)liveUpdateInterval:(id)sender { if (sender == cpuInterval) { [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(cpuPrefChange:) - object:cpuInterval]; + object:cpuInterval]; [self performSelector:@selector(cpuPrefChange:) withObject:cpuInterval afterDelay:0.0]; [cpuIntervalDisplay takeDoubleValueFrom:cpuInterval]; - } else if (sender == diskInterval) { + } + else if (sender == diskInterval) { [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(diskPrefChange:) object:diskInterval]; @@ -469,7 +489,8 @@ - (IBAction)liveUpdateInterval:(id)sender { withObject:diskInterval afterDelay:0.0]; [diskIntervalDisplay takeDoubleValueFrom:diskInterval]; - } else if (sender == memInterval) { + } + else if (sender == memInterval) { [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(memPrefChange:) object:memInterval]; @@ -477,7 +498,8 @@ - (IBAction)liveUpdateInterval:(id)sender { withObject:memInterval afterDelay:0.0]; [memIntervalDisplay takeDoubleValueFrom:memInterval]; - } else if (sender == netInterval) { + } + else if (sender == netInterval) { [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(netPrefChange:) object:netInterval]; @@ -489,108 +511,129 @@ - (IBAction)liveUpdateInterval:(id)sender { } // liveUpdateInterval: --(int)cpuDisplayMode -{ - int r=0; - if([cpuPercentage state]==NSOnState) - r|=kCPUDisplayPercent; - if([cpuGraph state]==NSOnState) - r|=kCPUDisplayGraph; - if([cpuThermometer state]==NSOnState) - r|=kCPUDisplayThermometer; - if([cpuHorizontalThermometer state]==NSOnState) - r|=kCPUDisplayHorizontalThermometer; - return r; +- (int)cpuDisplayMode { + int r = 0; + if ([cpuPercentage state] == NSOnState) + r |= kCPUDisplayPercent; + if ([cpuGraph state] == NSOnState) + r |= kCPUDisplayGraph; + if ([cpuThermometer state] == NSOnState) + r |= kCPUDisplayThermometer; + else if ([cpuHorizontalThermometer state] == NSOnState) + r |= kCPUDisplayHorizontalThermometer; + return r; } + - (IBAction)cpuPrefChange:(id)sender { // Extra load handler if (([cpuMeterToggle state] == NSOnState) && ![self isExtraWithBundleIDLoaded:kCPUMenuBundleID]) { [self loadExtraAtURL:kCPUMenuURL withID:kCPUMenuBundleID]; - } else if (([cpuMeterToggle state] == NSOffState) && [self isExtraWithBundleIDLoaded:kCPUMenuBundleID]) { + } + else if (([cpuMeterToggle state] == NSOffState) && [self isExtraWithBundleIDLoaded:kCPUMenuBundleID]) { [self removeExtraWithBundleID:kCPUMenuBundleID]; } [cpuMeterToggle setState:([self isExtraWithBundleIDLoaded:kCPUMenuBundleID] ? NSOnState : NSOffState)]; // Save changes - if (sender == cpuPercentage - || sender == cpuGraph - || sender == cpuThermometer - || sender == cpuHorizontalThermometer) { + if (sender == cpuPercentage || sender == cpuGraph || sender == cpuThermometer || sender == cpuHorizontalThermometer) { + + if (sender == cpuThermometer && cpuThermometer.state == NSOnState) { + cpuHorizontalThermometer.state = NSOffState; + } + else if (sender == cpuHorizontalThermometer && cpuHorizontalThermometer.state == NSOnState) { + cpuThermometer.state = NSOffState; + } [ourPrefs saveCpuDisplayMode:[self cpuDisplayMode]]; - } else if (sender == cpuTemperatureToggle) { - bool show = ([cpuTemperatureToggle state] == NSOnState) ? YES : NO; - [ourPrefs saveCpuTemperature:show]; - } else if (sender == cpuTemperatureUnit) { - [ourPrefs saveCpuTemperatureUnit:(int)[cpuTemperatureUnit indexOfSelectedItem]]; - } else if (sender==cpuTemperatureSensor){ - NSString*sensor=[cpuTemperatureSensor selectedItem].toolTip; - if([sensor isEqualToString:[TemperatureReader defaultSensor]]){ - sensor=kCPUTemperatureSensorDefault; - } - [ourPrefs saveCpuTemperatureSensor:sensor]; - } else if (sender == cpuInterval) { + } + else if (sender == cpuTemperatureToggle) { + bool show = ([cpuTemperatureToggle state] == NSOnState) ? YES : NO; + [ourPrefs saveCpuTemperature:show]; + } + else if (sender == cpuTemperatureUnit) { + [ourPrefs saveCpuTemperatureUnit:(int)[cpuTemperatureUnit indexOfSelectedItem]]; + } + else if (sender == cpuTemperatureSensor) { + NSString *sensor = [cpuTemperatureSensor selectedItem].toolTip; + if ([sensor isEqualToString:[TemperatureReader defaultSensor]]) { + sensor = kCPUTemperatureSensorDefault; + } + [ourPrefs saveCpuTemperatureSensor:sensor]; + } + else if (sender == cpuInterval) { [ourPrefs saveCpuInterval:[cpuInterval doubleValue]]; - } else if (sender == cpuPercentMode) { + } + else if (sender == cpuPercentMode) { [ourPrefs saveCpuPercentDisplay:(int)[cpuPercentMode indexOfSelectedItem]]; - } else if (sender == cpuMaxProcessCount) { - [ourPrefs saveCpuMaxProcessCount:(int)[cpuMaxProcessCount intValue]]; - } else if (sender == cpuGraphWidth) { + } + else if (sender == cpuMaxProcessCount) { + [ourPrefs saveCpuMaxProcessCount:[cpuMaxProcessCount intValue]]; + } + else if (sender == cpuGraphWidth) { [ourPrefs saveCpuGraphLength:[cpuGraphWidth intValue]]; - } else if (sender == cpuHorizontalRows) { - [ourPrefs saveCpuHorizontalRows:[cpuHorizontalRows intValue]]; - } else if (sender == cpuMenuWidth) { - [ourPrefs saveCpuMenuWidth:[cpuMenuWidth intValue]]; - } else if (sender == cpuMultipleCPU) { - switch([cpuMultipleCPU indexOfSelectedItem]){ - case 0: - [ourPrefs saveCpuAvgLowerHalfProcs:NO]; - [ourPrefs saveCpuAvgAllProcs:NO]; - [ourPrefs saveCpuSumAllProcsPercent:NO]; - [ourPrefs saveCpuSortByUsage:NO]; - break; - case 1: - [ourPrefs saveCpuAvgLowerHalfProcs:YES]; - [ourPrefs saveCpuAvgAllProcs:NO]; - [ourPrefs saveCpuSumAllProcsPercent:NO]; - [ourPrefs saveCpuSortByUsage:NO]; - break; - case 2: - [ourPrefs saveCpuAvgLowerHalfProcs:NO]; - [ourPrefs saveCpuAvgAllProcs:YES]; - [ourPrefs saveCpuSumAllProcsPercent:NO]; - [ourPrefs saveCpuSortByUsage:NO]; - break; - case 3: - [ourPrefs saveCpuAvgLowerHalfProcs:NO]; - [ourPrefs saveCpuAvgAllProcs:YES]; - [ourPrefs saveCpuSumAllProcsPercent:YES]; - [ourPrefs saveCpuSortByUsage:NO]; - break; - case 4: - [ourPrefs saveCpuAvgLowerHalfProcs:NO]; - [ourPrefs saveCpuAvgAllProcs:NO]; - [ourPrefs saveCpuSumAllProcsPercent:NO]; - [ourPrefs saveCpuSortByUsage:YES]; - break; - default: - [ourPrefs saveCpuAvgLowerHalfProcs:NO]; - [ourPrefs saveCpuAvgAllProcs:NO]; - [ourPrefs saveCpuSumAllProcsPercent:NO]; - [ourPrefs saveCpuSortByUsage:NO]; - break; - } - } else if (sender == cpuPowerMate) { + } + else if (sender == cpuHorizontalRows) { + [ourPrefs saveCpuHorizontalRows:[cpuHorizontalRows intValue]]; + } + else if (sender == cpuMenuWidth) { + [ourPrefs saveCpuMenuWidth:[cpuMenuWidth intValue]]; + } + else if (sender == cpuMultipleCPU) { + switch ([cpuMultipleCPU indexOfSelectedItem]) { + case 0: + [ourPrefs saveCpuAvgLowerHalfProcs:NO]; + [ourPrefs saveCpuAvgAllProcs:NO]; + [ourPrefs saveCpuSumAllProcsPercent:NO]; + [ourPrefs saveCpuSortByUsage:NO]; + break; + case 1: + [ourPrefs saveCpuAvgLowerHalfProcs:YES]; + [ourPrefs saveCpuAvgAllProcs:NO]; + [ourPrefs saveCpuSumAllProcsPercent:NO]; + [ourPrefs saveCpuSortByUsage:NO]; + break; + case 2: + [ourPrefs saveCpuAvgLowerHalfProcs:NO]; + [ourPrefs saveCpuAvgAllProcs:YES]; + [ourPrefs saveCpuSumAllProcsPercent:NO]; + [ourPrefs saveCpuSortByUsage:NO]; + break; + case 3: + [ourPrefs saveCpuAvgLowerHalfProcs:NO]; + [ourPrefs saveCpuAvgAllProcs:YES]; + [ourPrefs saveCpuSumAllProcsPercent:YES]; + [ourPrefs saveCpuSortByUsage:NO]; + break; + case 4: + [ourPrefs saveCpuAvgLowerHalfProcs:NO]; + [ourPrefs saveCpuAvgAllProcs:NO]; + [ourPrefs saveCpuSumAllProcsPercent:NO]; + [ourPrefs saveCpuSortByUsage:YES]; + break; + default: + [ourPrefs saveCpuAvgLowerHalfProcs:NO]; + [ourPrefs saveCpuAvgAllProcs:NO]; + [ourPrefs saveCpuSumAllProcsPercent:NO]; + [ourPrefs saveCpuSortByUsage:NO]; + break; + } + } + else if (sender == cpuPowerMate) { [ourPrefs saveCpuPowerMate:(([cpuPowerMate state] == NSOnState) ? YES : NO)]; - } else if (sender == cpuPowerMateMode) { + } + else if (sender == cpuPowerMateMode) { [ourPrefs saveCpuPowerMateMode:(int)[cpuPowerMateMode indexOfSelectedItem]]; - } else if (sender == cpuUserColor) { + } + else if (sender == cpuUserColor) { [ourPrefs saveCpuUserColor:[cpuUserColor color]]; - } else if (sender == cpuSystemColor) { + } + else if (sender == cpuSystemColor) { [ourPrefs saveCpuSystemColor:[cpuSystemColor color]]; - } else if (sender == cpuTemperatureColor) { - [ourPrefs saveCpuTemperatureColor:[cpuTemperatureColor color]]; - } else if (!sender) { + } + else if (sender == cpuTemperatureColor) { + [ourPrefs saveCpuTemperatureColor:[cpuTemperatureColor color]]; + } + else if (!sender) { // On first load handle multiprocs options if (![self isMultiProcessor]) { [ourPrefs saveCpuAvgAllProcs:NO]; @@ -599,96 +642,107 @@ - (IBAction)cpuPrefChange:(id)sender { } // Update controls - [cpuPercentage setState:([ourPrefs cpuDisplayMode]&kCPUDisplayPercent)?NSOnState:NSOffState]; - [cpuGraph setState:([ourPrefs cpuDisplayMode]&kCPUDisplayGraph)?NSOnState:NSOffState]; - [cpuThermometer setState:([ourPrefs cpuDisplayMode]&kCPUDisplayThermometer)?NSOnState:NSOffState]; - [cpuHorizontalThermometer setState:([ourPrefs cpuDisplayMode]&kCPUDisplayHorizontalThermometer)?NSOnState:NSOffState]; - if([cpuHorizontalThermometer state]==NSOnState){ - [cpuPercentage setEnabled:NO]; - [cpuGraph setEnabled:NO]; - [cpuThermometer setEnabled:NO]; - }else{ - [cpuPercentage setEnabled:YES]; - [cpuGraph setEnabled:YES]; - [cpuThermometer setEnabled:YES]; - } - [cpuTemperatureToggle setState:[ourPrefs cpuShowTemperature]]; - [cpuTemperatureUnit selectItemAtIndex:[ourPrefs cpuTemperatureUnit]]; + int cpuDisplayMode = [ourPrefs cpuDisplayMode]; + [cpuPercentage setState:(cpuDisplayMode & kCPUDisplayPercent) ? NSOnState : NSOffState]; + [cpuGraph setState:(cpuDisplayMode & kCPUDisplayGraph) ? NSOnState : NSOffState]; + [cpuThermometer setState:(cpuDisplayMode & kCPUDisplayThermometer) ? NSOnState : NSOffState]; + [cpuHorizontalThermometer setState:(cpuDisplayMode & kCPUDisplayHorizontalThermometer) ? NSOnState : NSOffState]; + + if ([cpuHorizontalThermometer state] == NSOnState) { + [cpuPercentage setEnabled:NO]; + [cpuGraph setEnabled:NO]; + } + else { + [cpuPercentage setEnabled:YES]; + [cpuGraph setEnabled:YES]; + } + [cpuTemperatureToggle setState:[ourPrefs cpuShowTemperature]]; + [cpuTemperatureUnit selectItemAtIndex:[ourPrefs cpuTemperatureUnit]]; + if ([cpuTemperatureToggle state] == NSOnState) { + [cpuTemperatureSensor setEnabled:YES]; + } + else { + [cpuTemperatureSensor setEnabled:NO]; + } + [cpuInterval setDoubleValue:[ourPrefs cpuInterval]]; [cpuPercentMode selectItemAtIndex:-1]; // Work around multiselects. AppKit problem? [cpuPercentMode selectItemAtIndex:[ourPrefs cpuPercentDisplay]]; - [cpuMaxProcessCount setIntValue:[ourPrefs cpuMaxProcessCount]]; - [cpuMaxProcessCountCountLabel setStringValue:[NSString stringWithFormat:NSLocalizedString(@"(%d)", @"DO NOT LOCALIZE!!!"), - (short)[ourPrefs cpuMaxProcessCount]]]; + [cpuMaxProcessCount setIntValue:[ourPrefs cpuMaxProcessCount]]; + [cpuMaxProcessCountCountLabel setStringValue:[NSString stringWithFormat:NSLocalizedString(@"(%d)", @"DO NOT LOCALIZE!!!"), + [ourPrefs cpuMaxProcessCount]]]; [cpuGraphWidth setIntValue:[ourPrefs cpuGraphLength]]; - [cpuHorizontalRows setIntValue:[ourPrefs cpuHorizontalRows]]; - [cpuMenuWidth setIntValue:[ourPrefs cpuMenuWidth]]; - if([ourPrefs cpuSortByUsage]){ - [cpuMultipleCPU selectItemAtIndex:4]; - }else if([ourPrefs cpuSumAllProcsPercent]){ - [cpuMultipleCPU selectItemAtIndex:3]; - }else if([ourPrefs cpuAvgAllProcs]){ - [cpuMultipleCPU selectItemAtIndex:2]; - }else if([ourPrefs cpuAvgLowerHalfProcs]){ - [cpuMultipleCPU selectItemAtIndex:1]; - }else{ - [cpuMultipleCPU selectItemAtIndex:0]; - } + [cpuHorizontalRows setIntValue:[ourPrefs cpuHorizontalRows]]; + [cpuMenuWidth setIntValue:[ourPrefs cpuMenuWidth]]; + if ([ourPrefs cpuSortByUsage]) { + [cpuMultipleCPU selectItemAtIndex:4]; + } + else if ([ourPrefs cpuSumAllProcsPercent]) { + [cpuMultipleCPU selectItemAtIndex:3]; + } + else if ([ourPrefs cpuAvgAllProcs]) { + [cpuMultipleCPU selectItemAtIndex:2]; + } + else if ([ourPrefs cpuAvgLowerHalfProcs]) { + [cpuMultipleCPU selectItemAtIndex:1]; + } + else { + [cpuMultipleCPU selectItemAtIndex:0]; + } [cpuPowerMate setState:([ourPrefs cpuPowerMate] ? NSOnState : NSOffState)]; [cpuPowerMateMode selectItemAtIndex:-1]; // Work around multiselects. AppKit problem? [cpuPowerMateMode selectItemAtIndex:[ourPrefs cpuPowerMateMode]]; [cpuUserColor setColor:[ourPrefs cpuUserColor]]; [cpuSystemColor setColor:[ourPrefs cpuSystemColor]]; - [cpuTemperatureColor setColor:[ourPrefs cpuTemperatureColor]]; + [cpuTemperatureColor setColor:[ourPrefs cpuTemperatureColor]]; [cpuIntervalDisplay takeDoubleValueFrom:cpuInterval]; -/* if ([cpuPercentage state]==NSOnState) { + if ([cpuPercentage state] == NSOnState) { [cpuPercentMode setEnabled:YES]; - [cpuPercentModeLabel setTextColor:[NSColor controlTextColor]]; - } else { + } + else { [cpuPercentMode setEnabled:NO]; - [cpuPercentModeLabel setTextColor:[NSColor lightGrayColor]]; } - */ - if ([cpuGraph state]==NSOnState) { + + if ([cpuGraph state] == NSOnState) { [cpuGraphWidth setEnabled:YES]; [cpuGraphWidthLabel setTextColor:[NSColor controlTextColor]]; - } else { + } + else { [cpuGraphWidth setEnabled:NO]; - [cpuGraphWidthLabel setTextColor:[NSColor lightGrayColor]]; + [cpuGraphWidthLabel setTextColor:[NSColor disabledControlTextColor]]; } - if ([cpuHorizontalThermometer state]==NSOnState) { + if ([cpuHorizontalThermometer state] == NSOnState) { [cpuHorizontalRows setEnabled:YES]; [cpuHorizontalRowsLabel setTextColor:[NSColor controlTextColor]]; - [cpuMenuWidth setEnabled:YES]; - [cpuMenuWidthLabel setTextColor:[NSColor controlTextColor]]; - } - else { + [cpuMenuWidth setEnabled:YES]; + [cpuMenuWidthLabel setTextColor:[NSColor controlTextColor]]; + } + else { [cpuHorizontalRows setEnabled:NO]; - [cpuHorizontalRowsLabel setTextColor:[NSColor lightGrayColor]]; + [cpuHorizontalRowsLabel setTextColor:[NSColor disabledControlTextColor]]; [cpuMenuWidth setEnabled:NO]; - [cpuMenuWidthLabel setTextColor:[NSColor lightGrayColor]]; - } -/* if ((([cpuDisplayMode indexOfSelectedItem] + 1) & (kCPUDisplayGraph | kCPUDisplayThermometer | kCPUDisplayHorizontalThermometer)) || - ((([cpuDisplayMode indexOfSelectedItem] + 1) & kCPUDisplayPercent) && - ([cpuPercentMode indexOfSelectedItem] == kCPUPercentDisplaySplit))) {*/ - [cpuUserColor setEnabled:YES]; - [cpuSystemColor setEnabled:YES]; - [cpuUserColorLabel setTextColor:[NSColor controlTextColor]]; - [cpuSystemColorLabel setTextColor:[NSColor controlTextColor]]; -/* } else { - [cpuUserColor setEnabled:NO]; - [cpuSystemColor setEnabled:NO]; - [cpuUserColorLabel setTextColor:[NSColor lightGrayColor]]; - [cpuSystemColorLabel setTextColor:[NSColor lightGrayColor]]; - }*/ - - // Write prefs and notify - [ourPrefs syncWithDisk]; + [cpuMenuWidthLabel setTextColor:[NSColor disabledControlTextColor]]; + } + /* if ((([cpuDisplayMode indexOfSelectedItem] + 1) & (kCPUDisplayGraph | kCPUDisplayThermometer | kCPUDisplayHorizontalThermometer)) || + ((([cpuDisplayMode indexOfSelectedItem] + 1) & kCPUDisplayPercent) && + ([cpuPercentMode indexOfSelectedItem] == kCPUPercentDisplaySplit))) {*/ + [cpuUserColor setEnabled:YES]; + [cpuSystemColor setEnabled:YES]; + [cpuUserColorLabel setTextColor:[NSColor controlTextColor]]; + [cpuSystemColorLabel setTextColor:[NSColor controlTextColor]]; + /* } else { + [cpuUserColor setEnabled:NO]; + [cpuSystemColor setEnabled:NO]; + [cpuUserColorLabel setTextColor:[NSColor disabledControlTextColor]]; + [cpuSystemColorLabel setTextColor:[NSColor disabledControlTextColor]]; + }*/ + + // Notify if ([self isExtraWithBundleIDLoaded:kCPUMenuBundleID]) { [[NSNotificationCenter defaultCenter] postNotificationName:kCPUMenuBundleID - object:kPrefChangeNotification - userInfo:nil]; + object:kPrefChangeNotification + userInfo:nil]; } } // cpuPrefChange @@ -698,7 +752,8 @@ - (IBAction)diskPrefChange:(id)sender { // Extra load if (([diskMeterToggle state] == NSOnState) && ![self isExtraWithBundleIDLoaded:kDiskMenuBundleID]) { [self loadExtraAtURL:kDiskMenuURL withID:kDiskMenuBundleID]; - } else if (([diskMeterToggle state] == NSOffState) && [self isExtraWithBundleIDLoaded:kDiskMenuBundleID]) { + } + else if (([diskMeterToggle state] == NSOffState) && [self isExtraWithBundleIDLoaded:kDiskMenuBundleID]) { [self removeExtraWithBundleID:kDiskMenuBundleID]; } [diskMeterToggle setState:([self isExtraWithBundleIDLoaded:kDiskMenuBundleID] ? NSOnState : NSOffState)]; @@ -706,9 +761,11 @@ - (IBAction)diskPrefChange:(id)sender { // Save changes if (sender == diskImageSet) { [ourPrefs saveDiskImageset:(int)[diskImageSet indexOfSelectedItem]]; - } else if (sender == diskInterval) { + } + else if (sender == diskInterval) { [ourPrefs saveDiskInterval:[diskInterval doubleValue]]; - } else if (sender == diskSelectMode) { + } + else if (sender == diskSelectMode) { [ourPrefs saveDiskSelectMode:(int)[diskSelectMode indexOfSelectedItem]]; } @@ -720,12 +777,11 @@ - (IBAction)diskPrefChange:(id)sender { [diskSelectMode selectItemAtIndex:-1]; // Work around multiselects. AppKit problem? [diskSelectMode selectItemAtIndex:[ourPrefs diskSelectMode]]; - // Write prefs and notify - [ourPrefs syncWithDisk]; + // Notify if ([self isExtraWithBundleIDLoaded:kDiskMenuBundleID]) { [[NSNotificationCenter defaultCenter] postNotificationName:kDiskMenuBundleID - object:kPrefChangeNotification - userInfo:nil]; + object:kPrefChangeNotification + userInfo:nil]; } } // diskPrefChange @@ -735,7 +791,8 @@ - (IBAction)memPrefChange:(id)sender { // Extra load if (([memMeterToggle state] == NSOnState) && ![self isExtraWithBundleIDLoaded:kMemMenuBundleID]) { [self loadExtraAtURL:kMemMenuURL withID:kMemMenuBundleID]; - } else if (([memMeterToggle state] == NSOffState) && [self isExtraWithBundleIDLoaded:kMemMenuBundleID]) { + } + else if (([memMeterToggle state] == NSOffState) && [self isExtraWithBundleIDLoaded:kMemMenuBundleID]) { [self removeExtraWithBundleID:kMemMenuBundleID]; } [memMeterToggle setState:([self isExtraWithBundleIDLoaded:kMemMenuBundleID] ? NSOnState : NSOffState)]; @@ -743,41 +800,54 @@ - (IBAction)memPrefChange:(id)sender { // Save changes if (sender == memDisplayMode) { [ourPrefs saveMemDisplayMode:(int)[memDisplayMode indexOfSelectedItem] + 1]; - } else if (sender == memInterval) { + } + else if (sender == memInterval) { [ourPrefs saveMemInterval:[memInterval doubleValue]]; - } else if (sender == memFreeUsedLabeling) { + } + else if (sender == memFreeUsedLabeling) { [ourPrefs saveMemUsedFreeLabel:(([memFreeUsedLabeling state] == NSOnState) ? YES : NO)]; - } else if (sender == memPageIndicator) { + } + else if (sender == memPageIndicator) { [ourPrefs saveMemPageIndicator:(([memPageIndicator state] == NSOnState) ? YES : NO)]; - } else if (sender == memPressureMode) { - [ourPrefs saveMemPressure:(([memPressureMode state] == NSOnState) ? YES : NO)]; - } else if (sender == memGraphWidth) { + } + else if (sender == memPressureMode) { + [ourPrefs saveMemPressure:(([memPressureMode state] == NSOnState) ? YES : NO)]; + } + else if (sender == memGraphWidth) { [ourPrefs saveMemGraphLength:[memGraphWidth intValue]]; - } else if (sender == memActiveColor) { + } + else if (sender == memActiveColor) { [ourPrefs saveMemActiveColor:[memActiveColor color]]; - } else if (sender == memInactiveColor) { + } + else if (sender == memInactiveColor) { [ourPrefs saveMemInactiveColor:[memInactiveColor color]]; - } else if (sender == memWiredColor) { + } + else if (sender == memWiredColor) { [ourPrefs saveMemWireColor:[memWiredColor color]]; - } else if (sender == memCompressedColor) { + } + else if (sender == memCompressedColor) { [ourPrefs saveMemCompressedColor:[memCompressedColor color]]; - } else if (sender == memFreeColor) { + } + else if (sender == memFreeColor) { [ourPrefs saveMemFreeColor:[memFreeColor color]]; - } else if (sender == memUsedColor) { + } + else if (sender == memUsedColor) { [ourPrefs saveMemUsedColor:[memUsedColor color]]; - } else if (sender == memPageinColor) { + } + else if (sender == memPageinColor) { [ourPrefs saveMemPageInColor:[memPageinColor color]]; - } else if (sender == memPageoutColor) { + } + else if (sender == memPageoutColor) { [ourPrefs saveMemPageOutColor:[memPageoutColor color]]; } - + // Update controls [memDisplayMode selectItemAtIndex:-1]; // Work around multiselects. AppKit problem? [memDisplayMode selectItemAtIndex:[ourPrefs memDisplayMode] - 1]; [memInterval setDoubleValue:[ourPrefs memInterval]]; [memFreeUsedLabeling setState:([ourPrefs memUsedFreeLabel] ? NSOnState : NSOffState)]; [memPageIndicator setState:([ourPrefs memPageIndicator] ? NSOnState : NSOffState)]; - [memPressureMode setState:([ourPrefs memPressure] ? NSOnState : NSOffState)]; + [memPressureMode setState:([ourPrefs memPressure] ? NSOnState : NSOffState)]; [memGraphWidth setIntValue:[ourPrefs memGraphLength]]; [memActiveColor setColor:[ourPrefs memActiveColor]]; [memInactiveColor setColor:[ourPrefs memInactiveColor]]; @@ -794,40 +864,42 @@ - (IBAction)memPrefChange:(id)sender { (([memDisplayMode indexOfSelectedItem] + 1) == kMemDisplayBar) || (([memDisplayMode indexOfSelectedItem] + 1) == kMemDisplayGraph)) { [memFreeUsedLabeling setEnabled:NO]; - } else { + } + else { [memFreeUsedLabeling setEnabled:YES]; } if (([memDisplayMode indexOfSelectedItem] + 1) == kMemDisplayGraph) { [memGraphWidth setEnabled:YES]; [memGraphWidthLabel setTextColor:[NSColor controlTextColor]]; - } else { + } + else { [memGraphWidth setEnabled:NO]; - [memGraphWidthLabel setTextColor:[NSColor lightGrayColor]]; + [memGraphWidthLabel setTextColor:[NSColor disabledControlTextColor]]; } if ([memPageIndicator state] == NSOnState) { [memPageinColorLabel setTextColor:[NSColor controlTextColor]]; [memPageoutColorLabel setTextColor:[NSColor controlTextColor]]; [memPageinColor setEnabled:YES]; [memPageoutColor setEnabled:YES]; - } else { - [memPageinColorLabel setTextColor:[NSColor lightGrayColor]]; - [memPageoutColorLabel setTextColor:[NSColor lightGrayColor]]; + } + else { + [memPageinColorLabel setTextColor:[NSColor disabledControlTextColor]]; + [memPageoutColorLabel setTextColor:[NSColor disabledControlTextColor]]; [memPageinColor setEnabled:NO]; [memPageoutColor setEnabled:NO]; } -/* if (([memDisplayMode indexOfSelectedItem] +1) == kMemDisplayBar) { - [memPressureMode setEnabled:YES]; - } - else { - [memPressureMode setEnabled:NO]; - }*/ + /* if (([memDisplayMode indexOfSelectedItem] +1) == kMemDisplayBar) { + [memPressureMode setEnabled:YES]; + } + else { + [memPressureMode setEnabled:NO]; + }*/ - // Write prefs and notify - [ourPrefs syncWithDisk]; + // Notify if ([self isExtraWithBundleIDLoaded:kMemMenuBundleID]) { [[NSNotificationCenter defaultCenter] postNotificationName:kMemMenuBundleID - object:kPrefChangeNotification - userInfo:nil]; + object:kPrefChangeNotification + userInfo:nil]; } } // memPrefChange @@ -846,36 +918,50 @@ - (IBAction)netPrefChange:(id)sender { // Save changes if (sender == netDisplayMode) { [ourPrefs saveNetDisplayMode:(int)[netDisplayMode indexOfSelectedItem] + 1]; - } else if (sender == netDisplayOrientation) { + } + else if (sender == netDisplayOrientation) { [ourPrefs saveNetDisplayOrientation:(int)[netDisplayOrientation indexOfSelectedItem]]; - } else if (sender == netScaleMode) { + } + else if (sender == netScaleMode) { [ourPrefs saveNetScaleMode:(int)[netScaleMode indexOfSelectedItem]]; - } else if (sender == netScaleCalc) { + } + else if (sender == netScaleCalc) { [ourPrefs saveNetScaleCalc:(int)[netScaleCalc indexOfSelectedItem]]; - } else if (sender == netInterval) { + } + else if (sender == netInterval) { [ourPrefs saveNetInterval:[netInterval doubleValue]]; - } else if (sender == netThroughputLabeling) { + } + else if (sender == netThroughputLabeling) { [ourPrefs saveNetThroughputLabel:(([netThroughputLabeling state] == NSOnState) ? YES : NO)]; - } else if (sender == netThroughput1KBound) { + } + else if (sender == netThroughput1KBound) { [ourPrefs saveNetThroughput1KBound:(([netThroughput1KBound state] == NSOnState) ? YES : NO)]; - } else if (sender == netThroughputBits) { + } + else if (sender == netThroughputBits) { [ourPrefs saveNetThroughputBits:(([netThroughputBits state] == NSOnState) ? YES : NO)]; - } else if (sender == netGraphStyle) { + } + else if (sender == netGraphStyle) { [ourPrefs saveNetGraphStyle:(int)[netGraphStyle indexOfSelectedItem]]; - } else if (sender == netGraphWidth) { + } + else if (sender == netGraphWidth) { [ourPrefs saveNetGraphLength:[netGraphWidth intValue]]; - } else if (sender == netTxColor) { + } + else if (sender == netTxColor) { [ourPrefs saveNetTransmitColor:[netTxColor color]]; - } else if (sender == netRxColor) { + } + else if (sender == netRxColor) { [ourPrefs saveNetReceiveColor:[netRxColor color]]; - } else if (sender == netInactiveColor) { + } + else if (sender == netInactiveColor) { [ourPrefs saveNetInactiveColor:[netInactiveColor color]]; - } else if (sender == netPreferInterface) { + } + else if (sender == netPreferInterface) { NSMenuItem *menuItem = (NSMenuItem *)[netPreferInterface selectedItem]; if (menuItem) { if (([netPreferInterface indexOfSelectedItem] == 0) || ![menuItem representedObject]) { [ourPrefs saveNetPreferInterface:kNetPrimaryInterface]; - } else { + } + else { [ourPrefs saveNetPreferInterface:[menuItem representedObject]]; } } @@ -903,7 +989,8 @@ - (IBAction)netPrefChange:(id)sender { [netIntervalDisplay takeDoubleValueFrom:netInterval]; if ([[ourPrefs netPreferInterface] isEqualToString:kNetPrimaryInterface]) { [netPreferInterface selectItemAtIndex:0]; - } else { + } + else { BOOL foundBetterItem = NO; NSArray *itemsArray = [netPreferInterface itemArray]; if (itemsArray) { @@ -929,7 +1016,8 @@ - (IBAction)netPrefChange:(id)sender { [netThroughputLabeling setEnabled:YES]; [netThroughput1KBound setEnabled:YES]; [netThroughputBits setEnabled:YES]; - } else { + } + else { [netThroughputLabeling setEnabled:NO]; [netThroughput1KBound setEnabled:NO]; [netThroughputBits setEnabled:NO]; @@ -939,11 +1027,12 @@ - (IBAction)netPrefChange:(id)sender { [netGraphStyleLabel setTextColor:[NSColor controlTextColor]]; [netGraphWidth setEnabled:YES]; [netGraphWidthLabel setTextColor:[NSColor controlTextColor]]; - } else { + } + else { [netGraphStyle setEnabled:NO]; - [netGraphStyleLabel setTextColor:[NSColor lightGrayColor]]; + [netGraphStyleLabel setTextColor:[NSColor disabledControlTextColor]]; [netGraphWidth setEnabled:NO]; - [netGraphWidthLabel setTextColor:[NSColor lightGrayColor]]; + [netGraphWidthLabel setTextColor:[NSColor disabledControlTextColor]]; } if ((([netDisplayMode indexOfSelectedItem] + 1) & kNetDisplayArrows) || (([netDisplayMode indexOfSelectedItem] + 1) & kNetDisplayGraph)) { @@ -951,37 +1040,36 @@ - (IBAction)netPrefChange:(id)sender { [netScaleModeLabel setTextColor:[NSColor controlTextColor]]; [netScaleCalc setEnabled:YES]; [netScaleCalcLabel setTextColor:[NSColor controlTextColor]]; - } else { + } + else { [netScaleMode setEnabled:NO]; - [netScaleModeLabel setTextColor:[NSColor lightGrayColor]]; + [netScaleModeLabel setTextColor:[NSColor disabledControlTextColor]]; [netScaleCalc setEnabled:NO]; - [netScaleCalcLabel setTextColor:[NSColor lightGrayColor]]; + [netScaleCalcLabel setTextColor:[NSColor disabledControlTextColor]]; } - // Write prefs and notify - [ourPrefs syncWithDisk]; + // Notify if ([self isExtraWithBundleIDLoaded:kNetMenuBundleID]) { [[NSNotificationCenter defaultCenter] postNotificationName:kNetMenuBundleID - object:kPrefChangeNotification - userInfo:nil]; + object:kPrefChangeNotification + userInfo:nil]; } } // netPrefChange /////////////////////////////////////////////////////////////// // -// Menu extra manipulations +// Menu extra manipulations // /////////////////////////////////////////////////////////////// - (void)loadExtraAtURL:(NSURL *)extraURL withID:(NSString *)bundleID { #ifdef ELCAPITAN - [ourPrefs saveBoolPref:bundleID value:YES]; - [ourPrefs syncWithDisk]; - [[NSNotificationCenter defaultCenter] postNotificationName:bundleID - object:kPrefChangeNotification - userInfo:nil]; - return; + [ourPrefs saveBoolPref:bundleID value:YES]; + [[NSNotificationCenter defaultCenter] postNotificationName:bundleID + object:kPrefChangeNotification + userInfo:nil]; + return; #else // Load the crack. With MenuCracker 2.x multiple loads are allowed, so // we don't care if someone else has the MenuCracker 2.x bundle loaded. @@ -1017,20 +1105,19 @@ - (void)loadExtraAtURL:(NSURL *)extraURL withID:(NSString *)bundleID { } // loadExtraAtURL:withID: - (BOOL)isExtraWithBundleIDLoaded:(NSString *)bundleID { - return [ourPrefs loadBoolPref:bundleID defaultValue:YES]; + return [ourPrefs loadBoolPref:bundleID defaultValue:YES]; } // isExtraWithBundleIDLoaded - (void)removeExtraWithBundleID:(NSString *)bundleID { - [ourPrefs saveBoolPref:bundleID value:NO]; - [ourPrefs syncWithDisk]; - [[NSNotificationCenter defaultCenter] postNotificationName:bundleID - object:kPrefChangeNotification - userInfo:nil]; - if([self noMenuMeterLoaded]){ - [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - [self.window makeKeyAndOrderFront:self]; - } - return; + [ourPrefs saveBoolPref:bundleID value:NO]; + [[NSNotificationCenter defaultCenter] postNotificationName:bundleID + object:kPrefChangeNotification + userInfo:nil]; + if ([self noMenuMeterLoaded]) { + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + [self.window makeKeyAndOrderFront:self]; + } + return; } // removeExtraWithBundleID - (void)showMenuExtraErrorSheet { @@ -1057,7 +1144,7 @@ - (void)showMenuExtraErrorSheet { // context nil, // msg - @"%@", + @"%@", [[NSBundle bundleForClass:[self class]] localizedStringForKey:@"For instructions on enabling third-party menu extras please see the documentation." value:nil @@ -1067,7 +1154,7 @@ - (void)showMenuExtraErrorSheet { /////////////////////////////////////////////////////////////// // -// Net prefs update +// Net prefs update // /////////////////////////////////////////////////////////////// @@ -1103,31 +1190,35 @@ - (void)updateNetInterfaceMenu { NSEnumerator *serviceEnum = [serviceArray objectEnumerator]; NSString *serviceID = nil; - int selectIndex = 0; + int selectIndex = 0; while ((serviceID = [serviceEnum nextObject])) { NSString *longName = nil, *shortName = nil, *pppName = nil; // Get interface details NSDictionary *interfaceDict = [self sysconfigValueForKey: - [NSString stringWithFormat:@"Setup:/Network/Service/%@/Interface", serviceID]]; - if (!interfaceDict) continue; + [NSString stringWithFormat:@"Setup:/Network/Service/%@/Interface", serviceID]]; + if (!interfaceDict) + continue; // This code is a quasi-clone of the code in MenuMeterNetConfig. // Look there to see what all this means if ([interfaceDict objectForKey:@"UserDefinedName"]) { longName = [interfaceDict objectForKey:@"UserDefinedName"]; - } else if ([interfaceDict objectForKey:@"Hardware"]) { + } + else if ([interfaceDict objectForKey:@"Hardware"]) { longName = [interfaceDict objectForKey:@"Hardware"]; } if ([interfaceDict objectForKey:@"DeviceName"]) { shortName = [interfaceDict objectForKey:@"DeviceName"]; } NSDictionary *pppDict = [self sysconfigValueForKey: - [NSString stringWithFormat:@"State:/Network/Service/%@/PPP", serviceID]]; + [NSString stringWithFormat:@"State:/Network/Service/%@/PPP", serviceID]]; if (pppDict && [pppDict objectForKey:@"InterfaceName"]) { pppName = [pppDict objectForKey:@"InterfaceName"]; } // Now we can try to build the item - if (!shortName) continue; // Nothing to key off, bail - if (!longName) longName = @"Unknown Interface"; + if (!shortName) + continue; // Nothing to key off, bail + if (!longName) + longName = @"Unknown Interface"; if (!shortName && pppName) { // Swap pppName for short name shortName = pppName; @@ -1135,17 +1226,18 @@ - (void)updateNetInterfaceMenu { } if (longName && shortName && pppName) { NSMenuItem *newMenuItem = (NSMenuItem *)[popupMenu addItemWithTitle: - [NSString stringWithFormat:@"%@ (%@, %@)", longName, shortName, pppName] - action:nil - keyEquivalent:@""]; + [NSString stringWithFormat:@"%@ (%@, %@)", longName, shortName, pppName] + action:nil + keyEquivalent:@""]; [newMenuItem setRepresentedObject:shortName]; // Update the selected index if appropriate if ([shortName isEqualToString:[ourPrefs netPreferInterface]]) { selectIndex = (int)[popupMenu numberOfItems] - 1; } - } else if (longName && shortName) { + } + else if (longName && shortName) { NSMenuItem *newMenuItem = (NSMenuItem *)[popupMenu addItemWithTitle: - [NSString stringWithFormat:@"%@ (%@)", longName, shortName] + [NSString stringWithFormat:@"%@ (%@)", longName, shortName] action:nil keyEquivalent:@""]; [newMenuItem setRepresentedObject:shortName]; @@ -1167,7 +1259,7 @@ - (void)updateNetInterfaceMenu { /////////////////////////////////////////////////////////////// // -// CPU info +// CPU info // /////////////////////////////////////////////////////////////// @@ -1175,11 +1267,13 @@ - (BOOL)isMultiProcessor { uint32_t cpuCount = 0; size_t sysctlLength = sizeof(cpuCount); - int mib[2] = { CTL_HW, HW_NCPU }; - if (sysctl(mib, 2, &cpuCount, &sysctlLength, NULL, 0)) return NO; + int mib[2] = {CTL_HW, HW_NCPU}; + if (sysctl(mib, 2, &cpuCount, &sysctlLength, NULL, 0)) + return NO; if (cpuCount > 1) { return YES; - } else { + } + else { return NO; } @@ -1187,7 +1281,7 @@ - (BOOL)isMultiProcessor { /////////////////////////////////////////////////////////////// // -// System config framework +// System config framework // /////////////////////////////////////////////////////////////// @@ -1196,7 +1290,7 @@ - (void)connectSystemConfig { // Create the callback context SCDynamicStoreContext scContext; scContext.version = 0; - scContext.info = (__bridge void * _Nullable)(self); + scContext.info = (__bridge void *_Nullable)(self); scContext.retain = NULL; scContext.release = NULL; scContext.copyDescription = NULL; @@ -1215,11 +1309,11 @@ - (void)connectSystemConfig { // Install notification run source if (!SCDynamicStoreSetNotificationKeys(scSession, (CFArrayRef)[NSArray arrayWithObjects: - @"State:/Network/Global/IPv4", - @"Setup:/Network/Global/IPv4", - @"State:/Network/Interface", nil], + @"State:/Network/Global/IPv4", + @"Setup:/Network/Global/IPv4", + @"State:/Network/Interface", nil], (CFArrayRef)[NSArray arrayWithObjects: - @"State:/Network/Interface.*", nil])) { + @"State:/Network/Interface.*", nil])) { NSLog(@"MenuMetersPref unable to install configd notification keys."); CFRelease(scSession); scSession = NULL; @@ -1255,7 +1349,8 @@ - (void)disconnectSystemConfig { - (NSDictionary *)sysconfigValueForKey:(NSString *)key { - if (!scSession) return nil; + if (!scSession) + return nil; return (NSDictionary *)CFBridgingRelease(SCDynamicStoreCopyValue(scSession, (CFStringRef)key)); } // sysconfigValueForKey diff --git a/PrefPane/de.lproj/MenuMetersPref.strings b/PrefPane/de.lproj/MenuMetersPref.strings index 5cf4299e..c30cf9ea 100644 --- a/PrefPane/de.lproj/MenuMetersPref.strings +++ b/PrefPane/de.lproj/MenuMetersPref.strings @@ -180,8 +180,8 @@ /* Class = "NSTextFieldCell"; title = "x"; ObjectID = "1007"; */ "1007.title" = "x"; -/* Class = "NSTextFieldCell"; title = "Aktualisierungsintervall (Sekunden):"; ObjectID = "1010"; */ -"1010.title" = "Aktualisierungsintervall (Sekunden):"; +/* Class = "NSTextFieldCell"; title = "Aktualisierungsintervall"; ObjectID = "1010"; */ +"1010.title" = "Aktualisierungsintervall"; /* Class = "NSTextFieldCell"; title = "Auswählen eines Volume aus dem Menü"; ObjectID = "1011"; */ "1011.title" = "Auswählen eines Volume aus dem Menü"; @@ -192,8 +192,8 @@ /* Class = "NSButtonCell"; title = "CPU Menu Meter zeigen"; ObjectID = "1014"; */ "1014.title" = "CPU Menu Meter zeigen"; -/* Class = "NSTextFieldCell"; title = "Aktualisierungsintervall (Sekunden):"; ObjectID = "1017"; */ -"1017.title" = "Aktualisierungsintervall (Sekunden):"; +/* Class = "NSTextFieldCell"; title = "Aktualisierungsintervall"; ObjectID = "1017"; */ +"1017.title" = "Aktualisierungsintervall"; /* Class = "NSTextFieldCell"; title = "x"; ObjectID = "1018"; */ "1018.title" = "x"; @@ -204,14 +204,14 @@ /* Class = "NSTextFieldCell"; title = "Systemauslastung"; ObjectID = "1020"; */ "1020.title" = "Systemauslastung"; -/* Class = "NSTextFieldCell"; title = "Prozentsatz zeigen als:"; ObjectID = "1022"; */ -"1022.title" = "Prozentsatz zeigen als:"; +/* Class = "NSTextFieldCell"; title = "Prozentsatz zeigen als"; ObjectID = "1022"; */ +"1022.title" = "Prozentsatz zeigen als"; /* Class = "NSButtonCell"; title = "Durchschnitt für alle Prozessoren zusammen anzeigen"; ObjectID = "1024"; */ "1024.title" = "Durchschnitt für alle Prozessoren zusammen anzeigen"; -/* Class = "NSTextFieldCell"; title = "Breite der Grafik:"; ObjectID = "1025"; */ -"1025.title" = "Breite der Grafik:"; +/* Class = "NSTextFieldCell"; title = "Breite der Grafik"; ObjectID = "1025"; */ +"1025.title" = "Breite"; /* Class = "NSTextFieldCell"; title = "Prozentsatzoptionen"; ObjectID = "1026"; */ "1026.title" = "Prozentsatzoptionen"; @@ -226,7 +226,7 @@ "1029.title" = "Farben"; /* Class = "NSButtonCell"; title = "PowerMate zeigt CPU-Benutzung durch"; ObjectID = "1030"; */ -"1030.title" = "PowerMate zeigt CPU-Benutzung durch"; +"1030.title" = "PowerMate zeigt CPU-Benutzung"; /* Class = "NSButtonCell"; title = "Speicher Menu Meter zeigen"; ObjectID = "1032"; */ "1032.title" = "Speicher Menu Meter zeigen"; @@ -234,8 +234,8 @@ /* Class = "NSTextFieldCell"; title = "x"; ObjectID = "1033"; */ "1033.title" = "x"; -/* Class = "NSTextFieldCell"; title = "Aktualisierungsintervall (Sekunden):"; ObjectID = "1035"; */ -"1035.title" = "Aktualisierungsintervall (Sekunden):"; +/* Class = "NSTextFieldCell"; title = "Aktualisierungsintervall"; ObjectID = "1035"; */ +"1035.title" = "Aktualisierungsintervall"; /* Class = "NSButtonCell"; title = "Benutzt/Frei beschriften"; ObjectID = "1037"; */ "1037.title" = "Benutzt/Frei beschriften"; @@ -258,8 +258,8 @@ /* Class = "NSTextFieldCell"; title = "Aktivität"; ObjectID = "1043"; */ "1043.title" = "Aktivität"; -/* Class = "NSTextFieldCell"; title = "Breite der Grafik:"; ObjectID = "1044"; */ -"1044.title" = "Breite der Grafik:"; +/* Class = "NSTextFieldCell"; title = "Breite"; ObjectID = "1044"; */ +"1044.title" = "Breite"; /* Class = "NSTextFieldCell"; title = "Grafikoptionen"; ObjectID = "1045"; */ "1045.title" = "Grafikoptionen"; @@ -285,8 +285,8 @@ /* Class = "NSButtonCell"; title = "Netzwerk Menu Meter zeigen"; ObjectID = "1054"; */ "1054.title" = "Netzwerk Menu Meter zeigen"; -/* Class = "NSTextFieldCell"; title = "Aktualisierungsintervall (Sekunden):"; ObjectID = "1056"; */ -"1056.title" = "Aktualisierungsintervall (Sekunden):"; +/* Class = "NSTextFieldCell"; title = "Aktualisierungsintervall (Sekunden)"; ObjectID = "1056"; */ +"1056.title" = "Aktualisierungsintervall"; /* Class = "NSTextFieldCell"; title = "Senden"; ObjectID = "1057"; */ "1057.title" = "Senden"; @@ -300,11 +300,11 @@ /* Class = "NSButtonCell"; title = "Werte unter 1KB/Sek. ignorieren"; ObjectID = "1061"; */ "1061.title" = "Werte unter 1KB/Sek. ignorieren"; -/* Class = "NSTextFieldCell"; title = "Grafikart:"; ObjectID = "1062"; */ -"1062.title" = "Grafikart:"; +/* Class = "NSTextFieldCell"; title = "Grafikart"; ObjectID = "1062"; */ +"1062.title" = "Grafikart"; -/* Class = "NSTextFieldCell"; title = "Breite der Grafik:"; ObjectID = "1063"; */ -"1063.title" = "Breite der Grafik:"; +/* Class = "NSTextFieldCell"; title = "Breite"; ObjectID = "1063"; */ +"1063.title" = "Breite"; /* Class = "NSTextFieldCell"; title = "Durchsatzanzeige"; ObjectID = "1065"; */ "1065.title" = "Durchsatzanzeige"; @@ -315,20 +315,20 @@ /* Class = "NSTextFieldCell"; title = "Farben"; ObjectID = "1067"; */ "1067.title" = "Farben"; -/* Class = "NSTextFieldCell"; title = "Angezeigte Schnittstelle:"; ObjectID = "1068"; */ -"1068.title" = "Angezeigte Schnittstelle:"; +/* Class = "NSTextFieldCell"; title = "Angezeigte Schnittstelle"; ObjectID = "1068"; */ +"1068.title" = "Angezeigte Schnittstelle"; /* Class = "NSTextFieldCell"; title = "Allgemein"; ObjectID = "1070"; */ "1070.title" = "Allgemein"; -/* Class = "NSTextFieldCell"; title = "Maßstab der Anzeige:"; ObjectID = "1071"; */ -"1071.title" = "Maßstab der Anzeige:"; +/* Class = "NSTextFieldCell"; title = "Maßstab der Anzeige"; ObjectID = "1071"; */ +"1071.title" = "Maßstab der Anzeige"; -/* Class = "NSTextFieldCell"; title = "Skalierung der Anzeige:"; ObjectID = "1073"; */ -"1073.title" = "Skalierung der Anzeige:"; +/* Class = "NSTextFieldCell"; title = "Skalierung der Anzeige"; ObjectID = "1073"; */ +"1073.title" = "Skalierung der Anzeige"; -/* Class = "NSTextFieldCell"; title = "Anzeigeausrichtung:"; ObjectID = "1075"; */ -"1075.title" = "Anzeigeausrichtung:"; +/* Class = "NSTextFieldCell"; title = "Anzeigeausrichtung"; ObjectID = "1075"; */ +"1075.title" = "Anzeigeausrichtung"; /* Class = "NSTextFieldCell"; title = "Inaktiv"; ObjectID = "1077"; */ "1077.title" = "Inaktiv"; @@ -339,8 +339,8 @@ /* Class = "NSButtonCell"; title = "Sort by CPU usage"; ObjectID = ""; */ ".title" = "Sort by CPU usage"; -/* Class = "NSTextFieldCell"; title = "Horizontal Rows:"; ObjectID = ""; */ -".title" = "Horizontal Rows:"; +/* Class = "NSTextFieldCell"; title = "Horizontal Rows"; ObjectID = ""; */ +".title" = "Rows"; /* Class = "NSTextFieldCell"; title = "Thermometer Display"; ObjectID = ""; */ ".title" = "Thermometer Display"; @@ -351,8 +351,8 @@ /* Class = "NSButtonCell"; title = "Show average for least utilized processors as single display"; ObjectID = ""; */ ".title" = "Show average for least utilized processors as single display"; -/* Class = "NSTextFieldCell"; title = "Horizontal Width:"; ObjectID = ""; */ -".title" = "Horizontal Width:"; +/* Class = "NSTextFieldCell"; title = "Horizontal Width"; ObjectID = ""; */ +".title" = "Width"; /* Class = "NSButtonCell"; title = "Zeige Speicherdruck"; ObjectID = "Ve2-cJ-Q8P"; */ "Ve2-cJ-Q8P.title" = "Zeige Speicherdruck"; @@ -406,16 +406,16 @@ "p2Z-13-y3b.title" = "Prozessoptionen"; /* title = "Processes to show:"; ObjectID = "rhi-NX-C3L"; */ -"rhi-NX-C3L.title" = "Max. Prozesse:"; +"rhi-NX-C3L.title" = "Max. Prozesse"; /* title = "Horizontal Thermometer Display"; ObjectID = "1094"; */ "1094.title" = "Thermometeroptionen"; -/* title = "Horizontal Rows:"; ObjectID = "1088"; */ -"1088.title" = "Horizontale Reihen"; +/* title = "Rows"; ObjectID = "1088"; */ +"1088.title" = "Reihen"; -/* title = "Horizontal Width:"; ObjectID = "1117"; */ -"1117.title" = "Horizontale Breite"; +/* title = "Width"; ObjectID = "1117"; */ +"1117.title" = "Breite"; /* title = "pure black/white"; ObjectID = "ayz-p2-XC5"; */ "ayz-p2-XC5.title" = "Schwarz-Weiß"; @@ -423,11 +423,11 @@ /* title = "original"; ObjectID = "FPO-Jo-ubG"; */ "FPO-Jo-ubG.title" = "Original"; -/* title = "Color tint:"; ObjectID = "mAZ-f2-5AJ"; */ -"mAZ-f2-5AJ.title" = "Farbton:"; +/* title = "Color tint"; ObjectID = "mAZ-f2-5AJ"; */ +"mAZ-f2-5AJ.title" = "Farbton"; -/* title = "Activity monitor:"; ObjectID = "CDM-3t-gon"; */ -"CDM-3t-gon.title" = "Aktivitätsanzeige:"; +/* title = "Activity monitor"; ObjectID = "CDM-3t-gon"; */ +"CDM-3t-gon.title" = "Aktivitätsanzeige"; /* title = "Opens specific panes"; ObjectID = "phH-yJ-I6O"; */ "phH-yJ-I6O.title" = "Öffnet entsprechende Kategorien"; diff --git a/PrefPane/en.lproj/Localizable.strings b/PrefPane/en.lproj/Localizable.strings new file mode 100644 index 00000000..44863eef --- /dev/null +++ b/PrefPane/en.lproj/Localizable.strings @@ -0,0 +1,3 @@ +/* DO NOT LOCALIZE!!! */ +"(%d)" = "(%d)"; + diff --git a/PrefPane/en.lproj/MenuMetersPref.strings b/PrefPane/en.lproj/MenuMetersPref.strings new file mode 100644 index 00000000..399a44a9 --- /dev/null +++ b/PrefPane/en.lproj/MenuMetersPref.strings @@ -0,0 +1,330 @@ + +/* MenuMeters */ +"12.title" = "MenuMeters"; + +/* Disk */ +"100.label" = "Disk"; + +/* CPU */ +"102.label" = "CPU"; + +/* Memory */ +"103.label" = "Memory"; + +/* Network */ +"105.label" = "Network"; + +/* ImageSet */ +"203.title" = "ImageSet"; + +/* Usage Bar */ +"219.title" = "Usage Bar"; + +/* Usage Chart */ +"225.title" = "Usage Chart"; + +/* Throughput */ +"294.title" = "Throughput"; + +/* Arrows */ +"297.title" = "Arrows"; + +/* Arrows and Throughput */ +"299.title" = "Arrows and Throughput"; + +/* Graph */ +"314.title" = "Graph"; + +/* Graph and Arrows */ +"363.title" = "Graph and Arrows"; + +/* Graph and Throughput */ +"365.title" = "Graph and Throughput"; + +/* Graph, Arrows and Throughput */ +"366.title" = "Graph, Arrows and Throughput"; + +/* Total (large text) */ +"384.title" = "Total (large text)"; + +/* User and System (small text) */ +"385.title" = "User and System (small text)"; + +/* Total (medium text) */ +"386.title" = "Total (medium text)"; + +/* Opposed */ +"404.title" = "Opposed"; + +/* Standard */ +"406.title" = "Standard"; + +/* Centered */ +"407.title" = "Centered"; + +/* Usage History Graph */ +"472.title" = "Usage History Graph"; + +/* pulse */ +"478.title" = "pulse"; + +/* glow */ +"479.title" = "glow"; + +/* Primary (automatic) */ +"487.title" = "Primary (automatic)"; + +/* inverse glow */ +"497.title" = "inverse glow"; + +/* inverse pulse */ +"498.title" = "inverse pulse"; + +/* opens the volume */ +"500.title" = "opens the volume"; + +/* unmounts/ejects the volume */ +"502.title" = "unmounts/ejects the volume"; + +/* Used/Free Totals */ +"508.title" = "Used/Free Totals"; + +/* Interface speed */ +"525.title" = "Interface speed"; + +/* Peak traffic */ +"526.title" = "Peak traffic"; + +/* Linear */ +"541.title" = "Linear"; + +/* Logarithmic */ +"545.title" = "Logarithmic"; + +/* Cube root */ +"556.title" = "Cube root"; + +/* Square root */ +"557.title" = "Square root"; + +/* Transmit/Receive */ +"590.title" = "Transmit/Receive"; + +/* Receive/Transmit */ +"592.title" = "Receive/Transmit"; + +/* Inverse Opposed */ +"613.title" = "Inverse Opposed"; + +/* Display Disk Activity Menu Meter */ +"1006.title" = "Display Disk Activity Menu Meter"; + +/* x */ +"1007.title" = "x"; + +/* Update interval: */ +"1010.title" = "Update interval:"; + +/* Selecting a volume from the disk menu */ +"1011.title" = "Selecting a volume from the disk menu"; + +/* (Holding the Option key will reverse the behavior) */ +"1013.title" = "(Holding the Option key will reverse the behavior)"; + +/* Display CPU Menu Meter */ +"1014.title" = "Display CPU Menu Meter"; + +/* Update interval: */ +"1017.title" = "Update interval:"; + +/* x */ +"1018.title" = "x"; + +/* User */ +"1019.title" = "User"; + +/* System */ +"1020.title" = "System"; + +/* Width */ +"1025.title" = "Width"; + +/* PowerMate shows CPU usage */ +"1030.title" = "PowerMate shows CPU usage"; + +/* Display Memory Menu Meter */ +"1032.title" = "Display Memory Menu Meter"; + +/* x */ +"1033.title" = "x"; + +/* Update interval: */ +"1035.title" = "Update interval:"; + +/* Show Used/Free labels */ +"1037.title" = "Show Used/Free labels"; + +/* Show paging activity indicator */ +"1039.title" = "Show paging activity indicator"; + +/* Pagein */ +"1041.title" = "Pagein"; + +/* Pageout */ +"1042.title" = "Pageout"; + +/* Graph width: */ +"1044.title" = "Graph width:"; + +/* Active */ +"1047.title" = "Active"; + +/* Inactive */ +"1048.title" = "Inactive"; + +/* Wired */ +"1049.title" = "Wired"; + +/* Free */ +"1050.title" = "Free"; + +/* Used */ +"1051.title" = "Used"; + +/* x */ +"1053.title" = "x"; + +/* Display Network Menu Meter */ +"1054.title" = "Display Network Menu Meter"; + +/* Update interval: */ +"1056.title" = "Update interval:"; + +/* Transmit */ +"1057.title" = "Transmit"; + +/* Receive */ +"1058.title" = "Receive"; + +/* Show throughput labels (Tx/Rx) */ +"1060.title" = "Show throughput labels (Tx/Rx)"; + +/* Ignore values below 1K/s */ +"1061.title" = "Ignore values below 1K/s"; + +/* Graph style: */ +"1062.title" = "Graph style:"; + +/* Graph width: */ +"1063.title" = "Graph width:"; + +/* Display prefers interface: */ +"1068.title" = "Display prefers interface:"; + +/* Display scales to: */ +"1071.title" = "Display scales to:"; + +/* Display scaling: */ +"1073.title" = "Display scaling:"; + +/* Display orientation: */ +"1075.title" = "Display orientation:"; + +/* Inactive */ +"1077.title" = "Inactive"; + +/* Rows */ +"1088.title" = "Rows"; + +/* Width */ +"1117.title" = "Width"; + +/* (%d) */ +"2NH-iF-l28.title" = "(%d)"; + +/* the sum of all cores */ +"5Lg-aP-TSR.title" = "the sum of all cores"; + +/* the average of all cores */ +"BYT-hf-ygS.title" = "the average of all cores"; + +/* Temperature */ +"C4n-F2-kuL.title" = "Temperature"; + +/* Activity monitor: */ +"CDM-3t-gon.title" = "Activity monitor:"; + +/* all cores sorted */ +"CG1-40-AVC.title" = "all cores sorted"; + +/* Sensor */ +"FHP-25-5gM.title" = "Sensor"; + +/* original */ +"FPO-Jo-ubG.title" = "original"; + +/* About */ +"FSw-QC-dn2.label" = "About"; + +/* physical cores only */ +"H5f-hN-vQV.title" = "physical cores only"; + +/* Graph */ +"IS4-Xc-psg.title" = "Graph"; + +/* Percentage */ +"Jeh-C2-Wwp.title" = "Percentage"; + +/* Show bits per second */ +"K7W-5f-1U8.title" = "Show bits per second"; + +/* Once per week */ +"LmO-Ij-G7M.title" = "Once per week"; + +/* Once per month */ +"PuG-eZ-jRm.title" = "Once per month"; + +/* Never */ +"STJ-3R-khe.title" = "Never"; + +/* Check updates now */ +"XYi-uP-QCD.title" = "Check updates now"; + +/* Display memory pressure */ +"aOw-Lj-aWS.title" = "Display memory pressure"; + +/* pure black/white */ +"ayz-p2-XC5.title" = "pure black/white"; + +/* Compressed */ +"ex0-hf-q5R.title" = "Compressed"; + +/* CPU Temperature */ +"fiY-Fv-rRZ.title" = "CPU Temperature"; + +/* Show */ +"k2d-Cg-pqL.title" = "Show"; + +/* Once per day */ +"lh5-j8-SRe.title" = "Once per day"; + +/* Color tint: */ +"mAZ-f2-5AJ.title" = "Color tint:"; + +/* Opens specific panes */ +"phH-yJ-I6O.title" = "Opens specific panes"; + +/* Vertical bar */ +"r6t-Zl-sS4.title" = "Vertical bar"; + +/* Processes to show: */ +"rhi-NX-C3L.title" = "Processes to show:"; + +/* Horizontal bar */ +"spo-WT-wCm.title" = "Horizontal bar"; + +/* Automatic update check interval: */ +"tug-YR-k7T.title" = "Automatic update check interval:"; + +/* all cores, including hyperthreaded ones */ +"vbH-jV-tUr.title" = "all cores, including hyperthreaded ones"; diff --git a/PrefPane/fi.lproj/MenuMetersPref.strings b/PrefPane/fi.lproj/MenuMetersPref.strings index 6e918f65..a8797c82 100644 --- a/PrefPane/fi.lproj/MenuMetersPref.strings +++ b/PrefPane/fi.lproj/MenuMetersPref.strings @@ -180,8 +180,8 @@ /* Class = "NSTextFieldCell"; title = "x"; ObjectID = "1007"; */ "1007.title" = "x"; -/* Class = "NSTextFieldCell"; title = "Update interval (seconds):"; ObjectID = "1010"; */ -"1010.title" = "Päivitysväli (sekunteina):"; +/* Class = "NSTextFieldCell"; title = "Update interval:"; ObjectID = "1010"; */ +"1010.title" = "Päivitysväli:"; /* Class = "NSTextFieldCell"; title = "Selecting a volume from the disk menu"; ObjectID = "1011"; */ "1011.title" = "Taltion valinta levyvalikosta"; @@ -192,8 +192,8 @@ /* Class = "NSButtonCell"; title = "Display CPU Menu Meter"; ObjectID = "1014"; */ "1014.title" = "Näytä prosessorin Menu Meter"; -/* Class = "NSTextFieldCell"; title = "Update interval (seconds):"; ObjectID = "1017"; */ -"1017.title" = "Päivitysväli (sekunteina):"; +/* Class = "NSTextFieldCell"; title = "Update interval:"; ObjectID = "1017"; */ +"1017.title" = "Päivitysväli:"; /* Class = "NSTextFieldCell"; title = "x"; ObjectID = "1018"; */ "1018.title" = "x"; @@ -231,8 +231,8 @@ /* Class = "NSTextFieldCell"; title = "x"; ObjectID = "1033"; */ "1033.title" = "x"; -/* Class = "NSTextFieldCell"; title = "Update interval (seconds):"; ObjectID = "1035"; */ -"1035.title" = "Päivitysväli (sekunteina):"; +/* Class = "NSTextFieldCell"; title = "Update interval:"; ObjectID = "1035"; */ +"1035.title" = "Päivitysväli:"; /* Class = "NSButtonCell"; title = "Show Used/Free labels"; ObjectID = "1037"; */ "1037.title" = "Näytä Käytössä/vapaana-nimiöt"; @@ -279,8 +279,8 @@ /* Class = "NSButtonCell"; title = "Display Network Menu Meter"; ObjectID = "1054"; */ "1054.title" = "Näytä verkon Menu Meter"; -/* Class = "NSTextFieldCell"; title = "Update interval (seconds):"; ObjectID = "1056"; */ -"1056.title" = "Päivitysväli (sekunteina):"; +/* Class = "NSTextFieldCell"; title = "Update interval:"; ObjectID = "1056"; */ +"1056.title" = "Päivitysväli:"; /* Class = "NSTextFieldCell"; title = "Transmit"; ObjectID = "1057"; */ "1057.title" = "Lähetys"; diff --git a/PrefPane/fr.lproj/MenuMetersPref.strings b/PrefPane/fr.lproj/MenuMetersPref.strings index 2dd46bd1..c0fbafb0 100644 --- a/PrefPane/fr.lproj/MenuMetersPref.strings +++ b/PrefPane/fr.lproj/MenuMetersPref.strings @@ -32,8 +32,8 @@ /* Class = "NSMenu"; title = "OtherViews"; ObjectID = "206"; */ "206.title" = "OtherViews"; -/* Class = "NSMenuItem"; title = "Barre d'usage"; ObjectID = "219"; */ -"219.title" = "Barre d'usage"; +/* Class = "NSMenuItem"; title = "Barre d’usage"; ObjectID = "219"; */ +"219.title" = "Barre d’usage"; /* Class = "NSMenu"; title = "OtherViews"; ObjectID = "223"; */ "223.title" = "OtherViews"; @@ -102,8 +102,8 @@ /* Class = "NSMenuItem"; title = "Centré"; ObjectID = "407"; */ "407.title" = "Centré"; -/* Class = "NSMenuItem"; title = "Historique d'usage"; ObjectID = "472"; */ -"472.title" = "Historique d'usage"; +/* Class = "NSMenuItem"; title = "Historique d’usage"; ObjectID = "472"; */ +"472.title" = "Historique d’usage"; /* Class = "NSMenu"; title = "OtherViews"; ObjectID = "477"; */ "477.title" = "OtherViews"; @@ -111,8 +111,8 @@ /* Class = "NSMenuItem"; title = "clignotant"; ObjectID = "478"; */ "478.title" = "clignotant"; -/* Class = "NSMenuItem"; title = "s'illuminant"; ObjectID = "479"; */ -"479.title" = "s'illuminant"; +/* Class = "NSMenuItem"; title = "s’illuminant"; ObjectID = "479"; */ +"479.title" = "s’illuminant"; /* Class = "NSMenuItem"; title = "Primaire (automatique)"; ObjectID = "487"; */ "487.title" = "Primaire (automatique)"; @@ -141,8 +141,8 @@ /* Class = "NSMenu"; title = "OtherViews"; ObjectID = "522"; */ "522.title" = "OtherViews"; -/* Class = "NSMenuItem"; title = "Vitesse du trafic sur l'interface"; ObjectID = "525"; */ -"525.title" = "Vitesse du trafic sur l'interface"; +/* Class = "NSMenuItem"; title = "Vitesse du trafic sur l’interface"; ObjectID = "525"; */ +"525.title" = "Vitesse du trafic sur l’interface"; /* Class = "NSMenuItem"; title = "Vitesse max. du trafic"; ObjectID = "526"; */ "526.title" = "Vitesse max. du trafic"; @@ -174,17 +174,17 @@ /* Class = "NSMenuItem"; title = "Opposition inversée"; ObjectID = "613"; */ "613.title" = "Opposition inversée"; -/* Class = "NSButtonCell"; title = "Afficher le menu d'Activité du disque"; ObjectID = "1006"; */ -"1006.title" = "Afficher le menu d'Activité du disque"; +/* Class = "NSButtonCell"; title = "Afficher le menu d’Activité du disque"; ObjectID = "1006"; */ +"1006.title" = "Afficher le menu d’Activité du disque"; /* Class = "NSTextFieldCell"; title = "x"; ObjectID = "1007"; */ "1007.title" = "x"; /* Class = "NSTextFieldCell"; title = "Intervalle (en seconde) de mise à jour : "; ObjectID = "1010"; */ -"1010.title" = "Intervalle (en seconde) de mise à jour : "; +"1010.title" = "Intervalle de mise à jour : "; -/* Class = "NSTextFieldCell"; title = "La sélection d'un volume dans le menu :"; ObjectID = "1011"; */ -"1011.title" = "La sélection d'un volume dans le menu :"; +/* Class = "NSTextFieldCell"; title = "La sélection d’un volume dans le menu :"; ObjectID = "1011"; */ +"1011.title" = "La sélection d’un volume dans le menu :"; /* Class = "NSTextFieldCell"; title = "(Maintenir la touche Option pour inverser le comportement)"; ObjectID = "1013"; */ "1013.title" = "(Maintenir la touche Option pour inverser le comportement)"; @@ -193,7 +193,7 @@ "1014.title" = "Afficher le menu CPU"; /* Class = "NSTextFieldCell"; title = "Intervalle (en seconde) de mise à jour : "; ObjectID = "1017"; */ -"1017.title" = "Intervalle (en seconde) de mise à jour : "; +"1017.title" = "Intervalle de mise à jour :"; /* Class = "NSTextFieldCell"; title = "x"; ObjectID = "1018"; */ "1018.title" = "x"; @@ -225,8 +225,8 @@ /* Class = "NSTextFieldCell"; title = "Couleurs"; ObjectID = "1029"; */ "1029.title" = "Couleurs"; -/* Class = "NSButtonCell"; title = "Le PowerMate affiche l'usage CPU en :"; ObjectID = "1030"; */ -"1030.title" = "Le PowerMate affiche l'usage CPU en :"; +/* Class = "NSButtonCell"; title = "Le PowerMate affiche l’usage CPU en :"; ObjectID = "1030"; */ +"1030.title" = "Le PowerMate affiche l’usage CPU"; /* Class = "NSButtonCell"; title = "Afficher le menu Mémoire"; ObjectID = "1032"; */ "1032.title" = "Afficher le menu Mémoire"; @@ -234,8 +234,8 @@ /* Class = "NSTextFieldCell"; title = "x"; ObjectID = "1033"; */ "1033.title" = "x"; -/* Class = "NSTextFieldCell"; title = "Intervalle (en seconde) de mise à jour : "; ObjectID = "1035"; */ -"1035.title" = "Intervalle (en seconde) de mise à jour : "; +/* Class = "NSTextFieldCell"; title = "Intervalle de mise à jour : "; ObjectID = "1035"; */ +"1035.title" = "Intervalle de mise à jour : "; /* Class = "NSButtonCell"; title = "Afficher les préfixes (Utilisée/Libre)"; ObjectID = "1037"; */ "1037.title" = "Afficher les préfixes (Utilisée/Libre)"; @@ -243,8 +243,8 @@ /* Class = "NSTextFieldCell"; title = "Général"; ObjectID = "1038"; */ "1038.title" = "Général"; -/* Class = "NSButtonCell"; title = "Afficher l'indicateur d'activité de la pagination"; ObjectID = "1039"; */ -"1039.title" = "Afficher l'indicateur d'activité de la pagination"; +/* Class = "NSButtonCell"; title = "Afficher l’indicateur d’activité de la pagination"; ObjectID = "1039"; */ +"1039.title" = "Afficher l’indicateur d’activité de la pagination"; /* Class = "NSTextFieldCell"; title = "Couleurs"; ObjectID = "1040"; */ "1040.title" = "Couleurs"; @@ -286,7 +286,7 @@ "1054.title" = "Afficher le menu Réseau"; /* Class = "NSTextFieldCell"; title = "Intervalle (en seconde) de mise à jour : "; ObjectID = "1056"; */ -"1056.title" = "Intervalle (en seconde) de mise à jour : "; +"1056.title" = "Intervalle de mise à jour:"; /* Class = "NSTextFieldCell"; title = "Transmission"; ObjectID = "1057"; */ "1057.title" = "Transmission"; diff --git a/PrefPane/it.lproj/MenuMetersPref.strings b/PrefPane/it.lproj/MenuMetersPref.strings index 8c6be2d3..1a21ef97 100644 --- a/PrefPane/it.lproj/MenuMetersPref.strings +++ b/PrefPane/it.lproj/MenuMetersPref.strings @@ -180,8 +180,8 @@ /* Class = "NSTextFieldCell"; title = "x"; ObjectID = "1007"; */ "1007.title" = "x"; -/* Class = "NSTextFieldCell"; title = "Intervallo Aggiornamento (secondi):"; ObjectID = "1010"; */ -"1010.title" = "Intervallo Aggiornamento (secondi):"; +/* Class = "NSTextFieldCell"; title = "Intervallo Aggiornamento:"; ObjectID = "1010"; */ +"1010.title" = "Intervallo Aggiornamento:"; /* Class = "NSTextFieldCell"; title = "Selezionare un volume dal menu disco"; ObjectID = "1011"; */ "1011.title" = "Selezionare un volume dal menu disco"; @@ -192,8 +192,8 @@ /* Class = "NSButtonCell"; title = "Mostra Menu Meter CPU"; ObjectID = "1014"; */ "1014.title" = "Mostra Menu Meter CPU"; -/* Class = "NSTextFieldCell"; title = "Intervallo Aggiornamento (secondi):"; ObjectID = "1017"; */ -"1017.title" = "Intervallo Aggiornamento (secondi):"; +/* Class = "NSTextFieldCell"; title = "Intervallo Aggiornamento:"; ObjectID = "1017"; */ +"1017.title" = "Intervallo Aggiornamento:"; /* Class = "NSTextFieldCell"; title = "x"; ObjectID = "1018"; */ "1018.title" = "x"; @@ -226,7 +226,7 @@ "1029.title" = "Colori"; /* Class = "NSButtonCell"; title = "PowerMate mostra uso CPU come"; ObjectID = "1030"; */ -"1030.title" = "PowerMate mostra uso CPU come"; +"1030.title" = "PowerMate mostra uso CPU"; /* Class = "NSButtonCell"; title = "Mostra Menu Meter Memoria"; ObjectID = "1032"; */ "1032.title" = "Mostra Menu Meter Memoria"; @@ -234,8 +234,8 @@ /* Class = "NSTextFieldCell"; title = "x"; ObjectID = "1033"; */ "1033.title" = "x"; -/* Class = "NSTextFieldCell"; title = "Intervallo Aggiornamento (secondi):"; ObjectID = "1035"; */ -"1035.title" = "Intervallo Aggiornamento (secondi):"; +/* Class = "NSTextFieldCell"; title = "Intervallo Aggiornamento:"; ObjectID = "1035"; */ +"1035.title" = "Intervallo Aggiornamento:"; /* Class = "NSButtonCell"; title = "Mostra etichette Usata/Libera"; ObjectID = "1037"; */ "1037.title" = "Mostra etichette Usata/Libera"; @@ -285,8 +285,8 @@ /* Class = "NSButtonCell"; title = "Mostra Menu Meter Network"; ObjectID = "1054"; */ "1054.title" = "Mostra Menu Meter Network"; -/* Class = "NSTextFieldCell"; title = "Intervallo Aggiornamento (secondi):"; ObjectID = "1056"; */ -"1056.title" = "Intervallo Aggiornamento (secondi):"; +/* Class = "NSTextFieldCell"; title = "Intervallo Aggiornamento:"; ObjectID = "1056"; */ +"1056.title" = "Intervallo Aggiornamento:"; /* Class = "NSTextFieldCell"; title = "Trasmetti"; ObjectID = "1057"; */ "1057.title" = "Trasmetti"; diff --git a/PrefPane/ja.lproj/MenuMetersPref.strings b/PrefPane/ja.lproj/MenuMetersPref.strings index 7fa76517..16f9a7ff 100644 --- a/PrefPane/ja.lproj/MenuMetersPref.strings +++ b/PrefPane/ja.lproj/MenuMetersPref.strings @@ -173,26 +173,26 @@ /* Class = "NSMenuItem"; title = "上下逆に"; ObjectID = "613"; */ "613.title" = "上下逆に"; -/* Class = "NSButtonCell"; title = "ディスクメータを表示:"; ObjectID = "1006"; */ -"1006.title" = "ディスクメータを表示:"; +/* Class = "NSButtonCell"; title = "ディスクメータを表示"; ObjectID = "1006"; */ +"1006.title" = "ディスクメータを表示"; /* Class = "NSTextFieldCell"; title = "x"; ObjectID = "1007"; */ "1007.title" = "x"; -/* Class = "NSTextFieldCell"; title = "更新間隔 (秒):"; ObjectID = "1010"; */ -"1010.title" = "更新間隔 (秒):"; +/* Class = "NSTextFieldCell"; title = "更新間隔"; ObjectID = "1010"; */ +"1010.title" = "更新間隔"; -/* Class = "NSTextFieldCell"; title = "メニューからボリューム選択した時:"; ObjectID = "1011"; */ -"1011.title" = "メニューからボリューム選択した時:"; +/* Class = "NSTextFieldCell"; title = "メニューからボリューム選択した時"; ObjectID = "1011"; */ +"1011.title" = "メニューからボリューム選択した時"; /* Class = "NSTextFieldCell"; title = "(Option キーを押すと取り消す事ができます)"; ObjectID = "1013"; */ "1013.title" = "(Option キーを押すと取り消す事ができます)"; -/* Class = "NSButtonCell"; title = "CPU メータを表示:"; ObjectID = "1014"; */ -"1014.title" = "CPU メータを表示:"; +/* Class = "NSButtonCell"; title = "CPU メータを表示"; ObjectID = "1014"; */ +"1014.title" = "CPU メータを表示"; -/* Class = "NSTextFieldCell"; title = "更新間隔 (秒):"; ObjectID = "1017"; */ -"1017.title" = "更新間隔 (秒):"; +/* Class = "NSTextFieldCell"; title = "更新間隔"; ObjectID = "1017"; */ +"1017.title" = "更新間隔"; /* Class = "NSTextFieldCell"; title = "x"; ObjectID = "1018"; */ "1018.title" = "x"; @@ -203,14 +203,14 @@ /* Class = "NSTextFieldCell"; title = "システム"; ObjectID = "1020"; */ "1020.title" = "システム"; -/* Class = "NSTextFieldCell"; title = "表示内容:"; ObjectID = "1022"; */ -"1022.title" = "表示内容:"; +/* Class = "NSTextFieldCell"; title = "表示内容"; ObjectID = "1022"; */ +"1022.title" = "表示内容"; /* Class = "NSButtonCell"; title = "マルチプロセッサの場合は平均値を表示"; ObjectID = "1024"; */ "1024.title" = "マルチプロセッサの場合は平均値を表示"; -/* Class = "NSTextFieldCell"; title = "幅:"; ObjectID = "1025"; */ -"1025.title" = "幅:"; +/* Class = "NSTextFieldCell"; title = "幅"; ObjectID = "1025"; */ +"1025.title" = "幅"; /* Class = "NSTextFieldCell"; title = "パーセント表示オプション"; ObjectID = "1026"; */ "1026.title" = "パーセント表示オプション"; @@ -224,17 +224,17 @@ /* Class = "NSTextFieldCell"; title = "カラーオプション"; ObjectID = "1029"; */ "1029.title" = "カラーオプション"; -/* Class = "NSButtonCell"; title = "PowerMate での CPU 使用表示:"; ObjectID = "1030"; */ -"1030.title" = "PowerMate での CPU 使用表示:"; +/* Class = "NSButtonCell"; title = "PowerMate での CPU 使用表示"; ObjectID = "1030"; */ +"1030.title" = "PowerMate で CPU 使用表示"; -/* Class = "NSButtonCell"; title = "メモリーメータを表示:"; ObjectID = "1032"; */ -"1032.title" = "メモリーメータを表示:"; +/* Class = "NSButtonCell"; title = "メモリーメータを表示"; ObjectID = "1032"; */ +"1032.title" = "メモリーメータを表示"; /* Class = "NSTextFieldCell"; title = "x"; ObjectID = "1033"; */ "1033.title" = "x"; -/* Class = "NSTextFieldCell"; title = "更新間隔 (秒):"; ObjectID = "1035"; */ -"1035.title" = "更新間隔 (秒):"; +/* Class = "NSTextFieldCell"; title = "更新間隔"; ObjectID = "1035"; */ +"1035.title" = "更新間隔"; /* Class = "NSButtonCell"; title = "use (使用量)/free (空き容量) のラベルを付ける"; ObjectID = "1037"; */ "1037.title" = "use (使用量)/free (空き容量) のラベルを付ける"; @@ -257,8 +257,8 @@ /* Class = "NSTextFieldCell"; title = "ページングレート"; ObjectID = "1043"; */ "1043.title" = "ページングレート"; -/* Class = "NSTextFieldCell"; title = "幅:"; ObjectID = "1044"; */ -"1044.title" = "幅:"; +/* Class = "NSTextFieldCell"; title = "幅"; ObjectID = "1044"; */ +"1044.title" = "幅"; /* Class = "NSTextFieldCell"; title = "グラフ表示オプション"; ObjectID = "1045"; */ "1045.title" = "グラフ表示オプション"; @@ -281,11 +281,11 @@ /* Class = "NSTextFieldCell"; title = "x"; ObjectID = "1053"; */ "1053.title" = "x"; -/* Class = "NSButtonCell"; title = "ネットワークメータを表示:"; ObjectID = "1054"; */ -"1054.title" = "ネットワークメータを表示:"; +/* Class = "NSButtonCell"; title = "ネットワークメータを表示"; ObjectID = "1054"; */ +"1054.title" = "ネットワークメータを表示"; -/* Class = "NSTextFieldCell"; title = "更新間隔 (秒):"; ObjectID = "1056"; */ -"1056.title" = "更新間隔 (秒):"; +/* Class = "NSTextFieldCell"; title = "更新間隔"; ObjectID = "1056"; */ +"1056.title" = "更新間隔"; /* Class = "NSTextFieldCell"; title = "送信"; ObjectID = "1057"; */ "1057.title" = "送信"; @@ -299,11 +299,11 @@ /* Class = "NSButtonCell"; title = "1KB/秒以下のスループットを無視"; ObjectID = "1061"; */ "1061.title" = "1KB/秒以下のスループットを無視"; -/* Class = "NSTextFieldCell"; title = "表示タイプ:"; ObjectID = "1062"; */ -"1062.title" = "表示タイプ:"; +/* Class = "NSTextFieldCell"; title = "表示タイプ"; ObjectID = "1062"; */ +"1062.title" = "表示タイプ"; -/* Class = "NSTextFieldCell"; title = "幅:"; ObjectID = "1063"; */ -"1063.title" = "幅:"; +/* Class = "NSTextFieldCell"; title = "幅"; ObjectID = "1063"; */ +"1063.title" = "幅"; /* Class = "NSTextFieldCell"; title = "スループット表示オプション"; ObjectID = "1065"; */ "1065.title" = "スループット表示オプション"; @@ -314,20 +314,20 @@ /* Class = "NSTextFieldCell"; title = "カラーオプション"; ObjectID = "1067"; */ "1067.title" = "カラーオプション"; -/* Class = "NSTextFieldCell"; title = "インターフェース表示:"; ObjectID = "1068"; */ -"1068.title" = "インターフェース表示:"; +/* Class = "NSTextFieldCell"; title = "インターフェース表示"; ObjectID = "1068"; */ +"1068.title" = "インターフェース表示"; /* Class = "NSTextFieldCell"; title = "一般オプション"; ObjectID = "1070"; */ "1070.title" = "一般オプション"; -/* Class = "NSTextFieldCell"; title = "表示内容:"; ObjectID = "1071"; */ -"1071.title" = "表示内容:"; +/* Class = "NSTextFieldCell"; title = "表示内容"; ObjectID = "1071"; */ +"1071.title" = "表示内容"; -/* Class = "NSTextFieldCell"; title = "スケール:"; ObjectID = "1073"; */ -"1073.title" = "スケール:"; +/* Class = "NSTextFieldCell"; title = "スケール"; ObjectID = "1073"; */ +"1073.title" = "スケール"; -/* Class = "NSTextFieldCell"; title = "表示方向:"; ObjectID = "1075"; */ -"1075.title" = "表示方向:"; +/* Class = "NSTextFieldCell"; title = "表示方向"; ObjectID = "1075"; */ +"1075.title" = "表示方向"; /* Class = "NSTextFieldCell"; title = "インアクティブ"; ObjectID = "1077"; */ "1077.title" = "インアクティブ"; diff --git a/PrefPane/zh-Hans.lproj/MenuMetersPref.strings b/PrefPane/zh-Hans.lproj/MenuMetersPref.strings index b6b04271..2aac3c02 100644 --- a/PrefPane/zh-Hans.lproj/MenuMetersPref.strings +++ b/PrefPane/zh-Hans.lproj/MenuMetersPref.strings @@ -180,8 +180,8 @@ /* Class = "NSTextFieldCell"; title = "x"; ObjectID = "1007"; */ "1007.title" = "x"; -/* Class = "NSTextFieldCell"; title = "更新间隔(秒):"; ObjectID = "1010"; */ -"1010.title" = "更新间隔(秒):"; +/* Class = "NSTextFieldCell"; title = "更新间隔:"; ObjectID = "1010"; */ +"1010.title" = "更新间隔:"; /* Class = "NSTextFieldCell"; title = "从磁盘菜单选择宗卷"; ObjectID = "1011"; */ "1011.title" = "从磁盘菜单选择宗卷"; @@ -192,8 +192,8 @@ /* Class = "NSButtonCell"; title = "显示 CPU 菜单仪表"; ObjectID = "1014"; */ "1014.title" = "显示 CPU 菜单仪表"; -/* Class = "NSTextFieldCell"; title = "更新间隔(秒):"; ObjectID = "1017"; */ -"1017.title" = "更新间隔(秒):"; +/* Class = "NSTextFieldCell"; title = "更新间隔:"; ObjectID = "1017"; */ +"1017.title" = "更新间隔:"; /* Class = "NSTextFieldCell"; title = "x"; ObjectID = "1018"; */ "1018.title" = "x"; @@ -234,8 +234,8 @@ /* Class = "NSTextFieldCell"; title = "x"; ObjectID = "1033"; */ "1033.title" = "x"; -/* Class = "NSTextFieldCell"; title = "更新间隔(秒):"; ObjectID = "1035"; */ -"1035.title" = "更新间隔(秒):"; +/* Class = "NSTextFieldCell"; title = "更新间隔:"; ObjectID = "1035"; */ +"1035.title" = "更新间隔:"; /* Class = "NSButtonCell"; title = "显示已使用/可用标签"; ObjectID = "1037"; */ "1037.title" = "显示已使用/可用标签"; @@ -285,8 +285,8 @@ /* Class = "NSButtonCell"; title = "显示网络菜单仪表"; ObjectID = "1054"; */ "1054.title" = "显示网络菜单仪表"; -/* Class = "NSTextFieldCell"; title = "更新间隔(秒):"; ObjectID = "1056"; */ -"1056.title" = "更新间隔(秒):"; +/* Class = "NSTextFieldCell"; title = "更新间隔:"; ObjectID = "1056"; */ +"1056.title" = "更新间隔:"; /* Class = "NSTextFieldCell"; title = "发送"; ObjectID = "1057"; */ "1057.title" = "发送"; diff --git a/hardware_reader/TemperatureReader.h b/hardware_reader/TemperatureReader.h index 1d762f36..1746376f 100644 --- a/hardware_reader/TemperatureReader.h +++ b/hardware_reader/TemperatureReader.h @@ -10,10 +10,15 @@ NS_ASSUME_NONNULL_BEGIN @interface TemperatureReader : NSObject -+(NSArray*)sensorNames; -+(NSString*)defaultSensor; -+(NSString*)displayNameForSensor:(NSString*)name; -+(float)temperatureOfSensorWithName:(NSString*)name; + ++ (NSArray *)sensorNames; + ++ (NSString *)defaultSensor; + ++ (NSString *)displayNameForSensor:(NSString *)name; + ++ (float)temperatureOfSensorWithName:(NSString *)name; + @end NS_ASSUME_NONNULL_END diff --git a/hardware_reader/TemperatureReader.m b/hardware_reader/TemperatureReader.m index c018d01d..d04f4fa4 100644 --- a/hardware_reader/TemperatureReader.m +++ b/hardware_reader/TemperatureReader.m @@ -13,99 +13,101 @@ #endif @implementation TemperatureReader -+(NSArray*)sensorNames -{ + ++ (NSArray *)sensorNames { #if TARGET_CPU_X86_64 - if (kIOReturnSuccess == SMCOpen()) { - UInt32 count; - NSMutableArray*a=[NSMutableArray array]; - SMCReadKeysCount(&count); - for(int i=0;i #import "applesilicon_hardware_reader.h" +#import // This code is based on https://github.com/fermion-star/apple_sensors/blob/master/temp_sensor.m // which was in turn based on https://github.com/freedomtan/sensors/blob/master/sensors/sensors.m // whose detail can be found in https://www2.slideshare.net/kstan2/exploring-thermal-related-stuff-in-idevices-using-opensource-tool - #include // Declarations from other IOKit source code @@ -28,58 +27,84 @@ IOHIDEventSystemClientRef IOHIDEventSystemClientCreate(CFAllocatorRef allocator); int IOHIDEventSystemClientSetMatching(IOHIDEventSystemClientRef client, CFDictionaryRef match); int IOHIDEventSystemClientSetMatchingMultiple(IOHIDEventSystemClientRef client, CFArrayRef match); -IOHIDEventRef IOHIDServiceClientCopyEvent(IOHIDServiceClientRef, int64_t , int32_t, int64_t); +IOHIDEventRef IOHIDServiceClientCopyEvent(IOHIDServiceClientRef, int64_t, int32_t, int64_t); CFTypeRef _Nullable IOHIDServiceClientCopyProperty(IOHIDServiceClientRef service, CFStringRef key); IOHIDFloat IOHIDEventGetFloatValue(IOHIDEventRef event, int32_t field); -//extern uint64_t my_mhz(void); -//extern void mybat(void); - // Primary Usage Page: - // kHIDPage_AppleVendor = 0xff00, - // kHIDPage_AppleVendorTemperatureSensor = 0xff05, - // kHIDPage_AppleVendorPowerSensor = 0xff08, - // - // Primary Usage: - // kHIDUsage_AppleVendor_TemperatureSensor = 0x0005, - // kHIDUsage_AppleVendorPowerSensor_Current = 0x0002, - // kHIDUsage_AppleVendorPowerSensor_Voltage = 0x0003, - // See IOHIDFamily/AppleHIDUsageTables.h for more information - // https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-701.60.2/IOHIDFamily/AppleHIDUsageTables.h.auto.html - - -#define IOHIDEventFieldBase(type) (type << 16) -#define kIOHIDEventTypeTemperature 15 -#define kIOHIDEventTypePower 25 - -NSDictionary*AppleSiliconTemperatureDictionary(void) -{ - NSDictionary*thermalSensors=@{@"PrimaryUsagePage":@(0xff00),@"PrimaryUsage":@(5)}; - - - IOHIDEventSystemClientRef system = IOHIDEventSystemClientCreate(kCFAllocatorDefault); // in CFBase.h = NULL - // ... this is the same as using kCFAllocatorDefault or the return value from CFAllocatorGetDefault() - IOHIDEventSystemClientSetMatching(system, (__bridge CFDictionaryRef)thermalSensors); - CFArrayRef matchingsrvs = IOHIDEventSystemClientCopyServices(system); // matchingsrvs = matching services - - - NSMutableDictionary*dict=[NSMutableDictionary dictionary]; - long count = CFArrayGetCount(matchingsrvs); - for (int i = 0; i < count; i++) { - IOHIDServiceClientRef sc = (IOHIDServiceClientRef)CFArrayGetValueAtIndex(matchingsrvs, i); - NSString* name = CFBridgingRelease(IOHIDServiceClientCopyProperty(sc, CFSTR("Product"))); // here we use ...CopyProperty - IOHIDEventRef event = IOHIDServiceClientCopyEvent(sc, kIOHIDEventTypeTemperature, 0, 0); // here we use ...CopyEvent - if (name && event) { - double temp = IOHIDEventGetFloatValue(event, IOHIDEventFieldBase(kIOHIDEventTypeTemperature)); - dict[name]=@(temp); - } - if (event) { - CFRelease(event); - } - } - - CFRelease(matchingsrvs); - CFRelease(system); - - return dict; - +// extern uint64_t my_mhz(void); +// extern void mybat(void); +// Primary Usage Page: +// kHIDPage_AppleVendor = 0xff00, +// kHIDPage_AppleVendorTemperatureSensor = 0xff05, +// kHIDPage_AppleVendorPowerSensor = 0xff08, +// +// Primary Usage: +// kHIDUsage_AppleVendor_TemperatureSensor = 0x0005, +// kHIDUsage_AppleVendorPowerSensor_Current = 0x0002, +// kHIDUsage_AppleVendorPowerSensor_Voltage = 0x0003, +// See IOHIDFamily/AppleHIDUsageTables.h for more information +// https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-701.60.2/IOHIDFamily/AppleHIDUsageTables.h.auto.html + +#define IOHIDEventFieldBase(type) (type << 16) +#define kIOHIDEventTypeTemperature 15 +#define kIOHIDEventTypePower 25 + +NSDictionary *AppleSiliconTemperatureDictionary(void) { + NSDictionary *thermalSensors = @{@"PrimaryUsagePage": @(0xff00), + @"PrimaryUsage": @(5)}; + + IOHIDEventSystemClientRef system = IOHIDEventSystemClientCreate(kCFAllocatorDefault); // in CFBase.h = NULL + // ... this is the same as using kCFAllocatorDefault or the return value from CFAllocatorGetDefault() + IOHIDEventSystemClientSetMatching(system, (__bridge CFDictionaryRef)thermalSensors); + CFArrayRef matchingsrvs = IOHIDEventSystemClientCopyServices(system); // matchingsrvs = matching services + + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + long count = CFArrayGetCount(matchingsrvs); + for (int i = 0; i < count; i++) { + IOHIDServiceClientRef sc = (IOHIDServiceClientRef)CFArrayGetValueAtIndex(matchingsrvs, i); + NSString *name = CFBridgingRelease(IOHIDServiceClientCopyProperty(sc, CFSTR("Product"))); // here we use ...CopyProperty + IOHIDEventRef event = IOHIDServiceClientCopyEvent(sc, kIOHIDEventTypeTemperature, 0, 0); // here we use ...CopyEvent + if (name && event) { + double temp = IOHIDEventGetFloatValue(event, IOHIDEventFieldBase(kIOHIDEventTypeTemperature)); + dict[name] = @(temp); + } + if (event) { + CFRelease(event); + } + } + + CFRelease(matchingsrvs); + CFRelease(system); + + return dict; +} + +float AppleSiliconTemperatureForName(NSString *productName) { + + NSDictionary *thermalSensors = @{@"PrimaryUsagePage": @(0xff00), + @"PrimaryUsage": @(5)}; + + IOHIDEventSystemClientRef system = IOHIDEventSystemClientCreate(kCFAllocatorDefault); // in CFBase.h = NULL + // ... this is the same as using kCFAllocatorDefault or the return value from CFAllocatorGetDefault() + IOHIDEventSystemClientSetMatching(system, (__bridge CFDictionaryRef)thermalSensors); + CFArrayRef matchingsrvs = IOHIDEventSystemClientCopyServices(system); // matchingsrvs = matching services + + long count = CFArrayGetCount(matchingsrvs); + float temp = 0; + for (int i = 0; i < count; i++) { + IOHIDServiceClientRef sc = (IOHIDServiceClientRef)CFArrayGetValueAtIndex(matchingsrvs, i); + NSString *name = CFBridgingRelease(IOHIDServiceClientCopyProperty(sc, CFSTR("Product"))); // here we use ...CopyProperty + if ([productName isEqualToString:name]) { + IOHIDEventRef event = IOHIDServiceClientCopyEvent(sc, kIOHIDEventTypeTemperature, 0, 0); // here we use ...CopyEvent + if (event) { + temp = IOHIDEventGetFloatValue(event, IOHIDEventFieldBase(kIOHIDEventTypeTemperature)); + CFRelease(event); + break; + } + } + } + CFRelease(matchingsrvs); + CFRelease(system); + + return temp; } diff --git a/hardware_reader/smc_reader.h b/hardware_reader/smc_reader.h index f2438183..eaf6f4a1 100644 --- a/hardware_reader/smc_reader.h +++ b/hardware_reader/smc_reader.h @@ -3,97 +3,100 @@ #include -#define IO_SERVICE_NAME "AppleSMC" - -#define KERNEL_INDEX_SMC 2 - -#define SMC_CMD_READ_BYTES 5 -#define SMC_CMD_WRITE_BYTES 6 -#define SMC_CMD_READ_INDEX 8 -#define SMC_CMD_READ_KEYINFO 9 -#define SMC_CMD_READ_PLIMIT 11 -#define SMC_CMD_READ_VERS 12 - -#define toSMCCode(str) (SMCCode){{str[3], str[2], str[1], str[0]}} - -#define SMC_DATATYPE_FPE2 toSMCCode("fpe2") -#define SMC_DATATYPE_FDS toSMCCode("{fds") -#define SMC_DATATYPE_UINT8 toSMCCode("ui8 ") -#define SMC_DATATYPE_UINT16 toSMCCode("ui16") -#define SMC_DATATYPE_UINT32 toSMCCode("ui32") -#define SMC_DATATYPE_SP78 toSMCCode("sp78") -#define SMC_DATATYPE_FLAG toSMCCode("flag") -#define SMC_DATATYPE_HEX toSMCCode("hex_") -#define SMC_DATATYPE_FLT toSMCCode("flt ") -#define SMC_DATATYPE_CH8 toSMCCode("ch8*") -#define SMC_DATATYPE_MSS toSMCCode("{mss") -#define SMC_DATATYPE_SI8 toSMCCode("si8 ") -#define SMC_DATATYPE_FP6A toSMCCode("fp6a") -#define SMC_DATATYPE_FP88 toSMCCode("fp88") -#define SMC_DATATYPE_JST toSMCCode("{jst") -#define SMC_DATATYPE_FP1F toSMCCode("fp1f") -#define SMC_DATATYPE_SI16 toSMCCode("si16") -#define SMC_DATATYPE_ALP toSMCCode("{alp") -#define SMC_DATATYPE_ALC toSMCCode("{alc") -#define SMC_DATATYPE_ALI toSMCCode("{ali") -#define SMC_DATATYPE_ALV toSMCCode("{alv") - -#define UI32_TO_UINT32(bytes) (bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3]) -#define UI16_TO_UINT32(bytes) (bytes[0] << 8 | bytes[1]) -#define UI8_TO_UINT32(bytes) (bytes[0]) -#define SP78_TO_CELSIUS(bytes) (UI16_TO_UINT32(bytes) / 256.0F) -#define FPE2_TO_UINT32(bytes) ((bytes[0] << 6) + (bytes[1] >> 2)) -#define FLAG_TO_UINT32(bytes) (bytes[0]) +#define IO_SERVICE_NAME "AppleSMC" + +#define KERNEL_INDEX_SMC 2 + +#define SMC_CMD_READ_BYTES 5 +#define SMC_CMD_WRITE_BYTES 6 +#define SMC_CMD_READ_INDEX 8 +#define SMC_CMD_READ_KEYINFO 9 +#define SMC_CMD_READ_PLIMIT 11 +#define SMC_CMD_READ_VERS 12 + +#define toSMCCode(str) \ + (SMCCode) { \ + { str[3], str[2], str[1], str[0] } \ + } + +#define SMC_DATATYPE_FPE2 toSMCCode("fpe2") +#define SMC_DATATYPE_FDS toSMCCode("{fds") +#define SMC_DATATYPE_UINT8 toSMCCode("ui8 ") +#define SMC_DATATYPE_UINT16 toSMCCode("ui16") +#define SMC_DATATYPE_UINT32 toSMCCode("ui32") +#define SMC_DATATYPE_SP78 toSMCCode("sp78") +#define SMC_DATATYPE_FLAG toSMCCode("flag") +#define SMC_DATATYPE_HEX toSMCCode("hex_") +#define SMC_DATATYPE_FLT toSMCCode("flt ") +#define SMC_DATATYPE_CH8 toSMCCode("ch8*") +#define SMC_DATATYPE_MSS toSMCCode("{mss") +#define SMC_DATATYPE_SI8 toSMCCode("si8 ") +#define SMC_DATATYPE_FP6A toSMCCode("fp6a") +#define SMC_DATATYPE_FP88 toSMCCode("fp88") +#define SMC_DATATYPE_JST toSMCCode("{jst") +#define SMC_DATATYPE_FP1F toSMCCode("fp1f") +#define SMC_DATATYPE_SI16 toSMCCode("si16") +#define SMC_DATATYPE_ALP toSMCCode("{alp") +#define SMC_DATATYPE_ALC toSMCCode("{alc") +#define SMC_DATATYPE_ALI toSMCCode("{ali") +#define SMC_DATATYPE_ALV toSMCCode("{alv") + +#define UI32_TO_UINT32(bytes) (bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3]) +#define UI16_TO_UINT32(bytes) (bytes[0] << 8 | bytes[1]) +#define UI8_TO_UINT32(bytes) (bytes[0]) +#define SP78_TO_CELSIUS(bytes) (UI16_TO_UINT32(bytes) / 256.0F) +#define FPE2_TO_UINT32(bytes) ((bytes[0] << 6) + (bytes[1] >> 2)) +#define FLAG_TO_UINT32(bytes) (bytes[0]) typedef union { - UInt8 code[4]; - UInt32 type; + UInt8 code[4]; + UInt32 type; } SMCCode; typedef struct { - UInt8 major; - UInt8 minor; - UInt8 build; - SInt8 reserved[1]; - UInt16 release; + UInt8 major; + UInt8 minor; + UInt8 build; + SInt8 reserved[1]; + UInt16 release; } SMCKeyDataVersion; typedef struct { - UInt16 version; - UInt16 length; - UInt32 cpuPLimit; - UInt32 gpuPLimit; - UInt32 memPLimit; + UInt16 version; + UInt16 length; + UInt32 cpuPLimit; + UInt32 gpuPLimit; + UInt32 memPLimit; } SMCKeyDataPLimitData; typedef struct { - UInt32 dataSize; - SMCCode dataType; - UInt8 dataAttributes; + UInt32 dataSize; + SMCCode dataType; + UInt8 dataAttributes; } SMCKeyDataKeyInfo; -typedef UInt8 SMCBytes[32]; +typedef UInt8 SMCBytes[32]; #define SMC_CALL_RESULT_SUCCESS 0 #define SMC_CALL_RESULT_ERROR 1 #define SMC_CALL_RESULT_NOT_FOUND 0x84 typedef struct { - SMCCode key; - SMCKeyDataVersion vers; - SMCKeyDataPLimitData pLimitData; - SMCKeyDataKeyInfo keyInfo; - UInt8 result; - UInt8 status; - UInt8 data8; - UInt32 data32; - SMCBytes bytes; + SMCCode key; + SMCKeyDataVersion vers; + SMCKeyDataPLimitData pLimitData; + SMCKeyDataKeyInfo keyInfo; + UInt8 result; + UInt8 status; + UInt8 data8; + UInt32 data32; + SMCBytes bytes; } SMCKeyData; typedef struct { - SMCCode key; - SMCKeyDataKeyInfo info; - SMCBytes bytes; + SMCCode key; + SMCKeyDataKeyInfo info; + SMCBytes bytes; } SMCKeyValue; kern_return_t SMCOpen(void); @@ -104,6 +107,6 @@ kern_return_t SMCReadKey(SMCCode key, SMCKeyValue *val); kern_return_t SMCReadKeysCount(UInt32 *count); kern_return_t SMCReadKeyAtIndex(UInt32 index, SMCKeyValue *val); -NSDictionary* SMCHumanReadableDescriptions(void); +NSDictionary *SMCHumanReadableDescriptions(void); #endif /* smc_reader_h */ diff --git a/hardware_reader/smc_reader.m b/hardware_reader/smc_reader.m index 472379e4..8941bb17 100644 --- a/hardware_reader/smc_reader.m +++ b/hardware_reader/smc_reader.m @@ -1,132 +1,115 @@ -#include #include "smc_reader.h" +#include static io_connect_t conn; -kern_return_t SMCOpen() -{ - kern_return_t result; - io_iterator_t iterator; - io_object_t device; - - result = IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching(IO_SERVICE_NAME), &iterator); - if (result != kIOReturnSuccess) - { - printf("Error: IOServiceGetMatchingServices() = %08x\n", result); - return result; - } - - device = IOIteratorNext(iterator); - IOObjectRelease(iterator); - if (!device) - { - printf("Error: no SMC found\n"); - return kIOReturnNoDevice; - } - - result = IOServiceOpen(device, mach_task_self(), 0, &conn); - IOObjectRelease(device); - if (result != kIOReturnSuccess) - { - printf("Error: IOServiceOpen() = %08x\n", result); - return result; - } - - return kIOReturnSuccess; +kern_return_t SMCOpen() { + kern_return_t result; + io_iterator_t iterator; + io_object_t device; + + result = IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching(IO_SERVICE_NAME), &iterator); + if (result != kIOReturnSuccess) { + printf("Error: IOServiceGetMatchingServices() = %08x\n", result); + return result; + } + + device = IOIteratorNext(iterator); + IOObjectRelease(iterator); + if (!device) { + printf("Error: no SMC found\n"); + return kIOReturnNoDevice; + } + + result = IOServiceOpen(device, mach_task_self(), 0, &conn); + IOObjectRelease(device); + if (result != kIOReturnSuccess) { + printf("Error: IOServiceOpen() = %08x\n", result); + return result; + } + + return kIOReturnSuccess; } -kern_return_t SMCClose() -{ - return IOServiceClose(conn); +kern_return_t SMCClose() { + return IOServiceClose(conn); } +kern_return_t SMCCall(int index, SMCKeyData *inputStructure, SMCKeyData *outputStructure) { + size_t structureInputSize; + size_t structureOutputSize; -kern_return_t SMCCall(int index, SMCKeyData *inputStructure, SMCKeyData *outputStructure) -{ - size_t structureInputSize; - size_t structureOutputSize; - - structureInputSize = sizeof(SMCKeyData); - structureOutputSize = sizeof(SMCKeyData); + structureInputSize = sizeof(SMCKeyData); + structureOutputSize = sizeof(SMCKeyData); - return IOConnectCallStructMethod(conn, index, - inputStructure, structureInputSize, - outputStructure, &structureOutputSize); + return IOConnectCallStructMethod(conn, index, + inputStructure, structureInputSize, + outputStructure, &structureOutputSize); } -kern_return_t SMCReadKey(SMCCode key, SMCKeyValue *val) -{ - kern_return_t result; - SMCKeyData inputStructure = {}; - SMCKeyData outputStructure = {}; - - inputStructure.key = key; - inputStructure.data8 = SMC_CMD_READ_KEYINFO; - - result = SMCCall(KERNEL_INDEX_SMC, &inputStructure, &outputStructure); - if (result != kIOReturnSuccess) - { - return result; - } - if (outputStructure.result != SMC_CALL_RESULT_SUCCESS) - { - return kIOReturnError; - } - - val->info = outputStructure.keyInfo; - - inputStructure.keyInfo.dataSize = val->info.dataSize; - inputStructure.data8 = SMC_CMD_READ_BYTES; - - result = SMCCall(KERNEL_INDEX_SMC, &inputStructure, &outputStructure); - if (result != kIOReturnSuccess) - { - return result; - } - if (outputStructure.result != SMC_CALL_RESULT_SUCCESS) - { - return kIOReturnError; - } - - memcpy(val->key.code, key.code, sizeof(val->key.code)); - memcpy(val->bytes, outputStructure.bytes, sizeof(outputStructure.bytes)); - - return kIOReturnSuccess; +kern_return_t SMCReadKey(SMCCode key, SMCKeyValue *val) { + kern_return_t result; + SMCKeyData inputStructure = {}; + SMCKeyData outputStructure = {}; + + inputStructure.key = key; + inputStructure.data8 = SMC_CMD_READ_KEYINFO; + + result = SMCCall(KERNEL_INDEX_SMC, &inputStructure, &outputStructure); + if (result != kIOReturnSuccess) { + return result; + } + if (outputStructure.result != SMC_CALL_RESULT_SUCCESS) { + return kIOReturnError; + } + + val->info = outputStructure.keyInfo; + + inputStructure.keyInfo.dataSize = val->info.dataSize; + inputStructure.data8 = SMC_CMD_READ_BYTES; + + result = SMCCall(KERNEL_INDEX_SMC, &inputStructure, &outputStructure); + if (result != kIOReturnSuccess) { + return result; + } + if (outputStructure.result != SMC_CALL_RESULT_SUCCESS) { + return kIOReturnError; + } + + memcpy(val->key.code, key.code, sizeof(val->key.code)); + memcpy(val->bytes, outputStructure.bytes, sizeof(outputStructure.bytes)); + + return kIOReturnSuccess; } -kern_return_t SMCReadKeysCount(UInt32 *count) -{ - kern_return_t result; - SMCKeyValue val = {}; - result = SMCReadKey(toSMCCode("#KEY"), &val); - if (result == kIOReturnSuccess && val.info.dataType.type == SMC_DATATYPE_UINT32.type) - { - *count = UI32_TO_UINT32(val.bytes); - } - return result; +kern_return_t SMCReadKeysCount(UInt32 *count) { + kern_return_t result; + SMCKeyValue val = {}; + result = SMCReadKey(toSMCCode("#KEY"), &val); + if (result == kIOReturnSuccess && val.info.dataType.type == SMC_DATATYPE_UINT32.type) { + *count = UI32_TO_UINT32(val.bytes); + } + return result; } -kern_return_t SMCReadKeyAtIndex(UInt32 index, SMCKeyValue *val) -{ - kern_return_t result; - SMCKeyData inputStructure = {}; - SMCKeyData outputStructure = {}; +kern_return_t SMCReadKeyAtIndex(UInt32 index, SMCKeyValue *val) { + kern_return_t result; + SMCKeyData inputStructure = {}; + SMCKeyData outputStructure = {}; - inputStructure.data32 = index; - inputStructure.data8 = SMC_CMD_READ_INDEX; + inputStructure.data32 = index; + inputStructure.data8 = SMC_CMD_READ_INDEX; - result = SMCCall(KERNEL_INDEX_SMC, &inputStructure, &outputStructure); - if (result != kIOReturnSuccess) - { - return result; - } + result = SMCCall(KERNEL_INDEX_SMC, &inputStructure, &outputStructure); + if (result != kIOReturnSuccess) { + return result; + } - if (outputStructure.result != SMC_CALL_RESULT_SUCCESS) - { - return kIOReturnError; - } + if (outputStructure.result != SMC_CALL_RESULT_SUCCESS) { + return kIOReturnError; + } - return SMCReadKey(outputStructure.key, val); + return SMCReadKey(outputStructure.key, val); } // modified from smc_dump_lib_keys @@ -137,84 +120,86 @@ kern_return_t SMCReadKeyAtIndex(UInt32 index, SMCKeyValue *val) #include struct PlatformKeyDescriptions { - char key[4]; - uint8_t index; - char description[256]; - uint8_t len; - uint16_t pad1; - char type[4]; - uint32_t pad2; /* added in 10.13.4 */ + char key[4]; + uint8_t index; + char description[256]; + uint8_t len; + uint16_t pad1; + char type[4]; + uint32_t pad2; /* added in 10.13.4 */ } __attribute__((packed)); struct PlatformStructLookup { - char branch[16]; - struct PlatformKeyDescriptions *descr[2]; - uint32_t descrn[2]; - uint32_t pad[2]; + char branch[16]; + struct PlatformKeyDescriptions *descr[2]; + uint32_t descrn[2]; + uint32_t pad[2]; }; -NSDictionary* SMCHumanReadableDescriptions(void) { - void *smc_lib = dlopen("/usr/lib/libSMC.dylib", RTLD_LAZY); - - if (smc_lib) { - struct PlatformStructLookup *lookup_arr = (struct PlatformStructLookup *)dlsym(smc_lib, "AccumulatorPlatformStructLookupArray"); - -/* if (!lookup_arr) { - // This library is normally in dyld shared cache, so we have to use DYLD_SHARED_REGION=avoid envvar. - // As a more convenient workaround we currently compile with an overlapping segment. - NSLog(@"Unable to solve AccumulatorPlatformStructLookupArray symbol, trying to brute-force...\n"); - - uint8_t *start = (uint8_t *)dlsym(smc_lib, "SMCReadKey"); - uint8_t *ptr = start; - char first[16] = "m87"; - while (ptr && memcmp(ptr, first, sizeof(first)) != 0) { - //printf("%08X: %02X\n", ptr-start, ptr[0]); - ptr++; - } - - lookup_arr = (struct PlatformStructLookup *)ptr; - } */ - NSMutableDictionary*dict=[NSMutableDictionary dictionary]; - if (lookup_arr) { - bool stop = false; - while (lookup_arr->branch[0] != '\0' && isascii(lookup_arr->branch[0]) && !stop) { -// printf("Dumping keys for %.4s...\n", lookup_arr->branch); - - for (uint32_t i = 0; i < 2 && !stop; i++) { - // printf(" Set %u has %u keys:\n", i, lookup_arr->descrn[i]); - for (uint32_t j = 0; j < lookup_arr->descrn[i]; j++) { - struct PlatformKeyDescriptions *key = &lookup_arr->descr[i][j]; - if (key->pad1 != 0 || key->pad2 != 0) { - stop = true; - break; - } - /* - printf(" [%c%c%c%c] type [%c%c%c%c] %02X%02X%02X%02X len [%2u] idx [%3u]: %.256s\n", - key->key[3] == '\0' ? ' ' : key->key[3], key->key[2] == '\0' ? ' ' : key->key[2], - key->key[1] == '\0' ? ' ' : key->key[1], key->key[0] == '\0' ? ' ' : key->key[0], - key->type[3], key->type[2], key->type[1], key->type[0] == '\0' ? '?' : key->type[3], - key->type[3], key->type[2], key->type[1], key->type[0], - key->len, key->index, key->description); - */ - char s[5]={key->key[3],key->key[2],key->key[1],key->key[0],0}; - NSString*smcKey=[NSString stringWithUTF8String:s]; - NSString*desc=[NSString stringWithUTF8String:key->description]; - dict[smcKey]=desc; - } - } - - lookup_arr++; - } - - dlclose(smc_lib); - return dict; - } else { - NSLog(@"Unable to locate lookup array in libSMC.dylib!"); - dlclose(smc_lib); - } - } else { - NSLog(@"Unable to open libSMC.dylib!"); - } - - return nil; +NSDictionary *SMCHumanReadableDescriptions(void) { + void *smc_lib = dlopen("/usr/lib/libSMC.dylib", RTLD_LAZY); + + if (smc_lib) { + struct PlatformStructLookup *lookup_arr = (struct PlatformStructLookup *)dlsym(smc_lib, "AccumulatorPlatformStructLookupArray"); + + /* if (!lookup_arr) { + // This library is normally in dyld shared cache, so we have to use DYLD_SHARED_REGION=avoid envvar. + // As a more convenient workaround we currently compile with an overlapping segment. + NSLog(@"Unable to solve AccumulatorPlatformStructLookupArray symbol, trying to brute-force...\n"); + + uint8_t *start = (uint8_t *)dlsym(smc_lib, "SMCReadKey"); + uint8_t *ptr = start; + char first[16] = "m87"; + while (ptr && memcmp(ptr, first, sizeof(first)) != 0) { + //printf("%08X: %02X\n", ptr-start, ptr[0]); + ptr++; + } + + lookup_arr = (struct PlatformStructLookup *)ptr; + } */ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (lookup_arr) { + bool stop = false; + while (lookup_arr->branch[0] != '\0' && isascii(lookup_arr->branch[0]) && !stop) { + // printf("Dumping keys for %.4s...\n", lookup_arr->branch); + + for (uint32_t i = 0; i < 2 && !stop; i++) { + // printf(" Set %u has %u keys:\n", i, lookup_arr->descrn[i]); + for (uint32_t j = 0; j < lookup_arr->descrn[i]; j++) { + struct PlatformKeyDescriptions *key = &lookup_arr->descr[i][j]; + if (key->pad1 != 0 || key->pad2 != 0) { + stop = true; + break; + } + /* + printf(" [%c%c%c%c] type [%c%c%c%c] %02X%02X%02X%02X len [%2u] idx [%3u]: %.256s\n", + key->key[3] == '\0' ? ' ' : key->key[3], key->key[2] == '\0' ? ' ' : key->key[2], + key->key[1] == '\0' ? ' ' : key->key[1], key->key[0] == '\0' ? ' ' : key->key[0], + key->type[3], key->type[2], key->type[1], key->type[0] == '\0' ? '?' : key->type[3], + key->type[3], key->type[2], key->type[1], key->type[0], + key->len, key->index, key->description); + */ + char s[5] = {key->key[3], key->key[2], key->key[1], key->key[0], 0}; + NSString *smcKey = [NSString stringWithUTF8String:s]; + NSString *desc = [NSString stringWithUTF8String:key->description]; + dict[smcKey] = desc; + } + } + + lookup_arr++; + } + + dlclose(smc_lib); + return dict; + } + else { + NSLog(@"Unable to locate lookup array in libSMC.dylib!"); + dlclose(smc_lib); + } + } + else { + NSLog(@"Unable to open libSMC.dylib!"); + } + + return nil; }