Changeset e36a3b3


Ignore:
Timestamp:
Mar 10, 2019 11:16:56 AM (17 months ago)
Author:
meeh <meeh@…>
Branches:
master
Children:
30dbe24
Parents:
5d389c8
Message:

Mac OSX Launcher:

  • Fixed startup option so the launcher can start at OSX login/bootup.
  • Added I2P Browser to the list of "firefox" browsers to detect.
  • Changed hardcoded path lookup to native "registry" lookup for firefox application.
  • Made the advanced preferences table editable by the user.
  • Cleanup of old and/or unused code.
  • Bugfixes.
Location:
launchers/macosx
Files:
1 added
15 edited

Legend:

Unmodified
Added
Removed
  • launchers/macosx/AppDelegate.h

    r5d389c8 re36a3b3  
    101101- (void) applicationDidFinishLaunching:(NSNotification *)aNotification;
    102102- (void) applicationWillTerminate:(NSNotification *)aNotification;
    103 - (void) setApplicationDefaultPreferences;
    104103- (AppDelegate *) initWithArgc:(int)argc argv:(const char **)argv;
    105104- (BOOL) userNotificationCenter:(NSUserNotificationCenter *)center
  • launchers/macosx/I2PLauncher/Base.lproj/UserInterfaces.xib

    r5d389c8 re36a3b3  
    11<?xml version="1.0" encoding="UTF-8"?>
    2 <document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     2<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
    33    <dependencies>
    44        <deployment identifier="macosx"/>
    5         <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14313.18"/>
     5        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
    66    </dependencies>
    77    <objects>
     
    3838            <point key="canvasLocation" x="17" y="167"/>
    3939        </menu>
     40        <menuItem title="Application" allowsKeyEquivalentWhenHidden="YES" id="84R-pF-Wt1">
     41            <modifierMask key="keyEquivalentModifierMask"/>
     42            <menu key="submenu" title="Application" id="Trv-j7-WYu">
     43                <items>
     44                    <menuItem title="About Application" id="XDp-94-iig">
     45                        <modifierMask key="keyEquivalentModifierMask"/>
     46                        <connections>
     47                            <action selector="orderFrontStandardAboutPanel:" target="-1" id="gJe-90-jzd"/>
     48                        </connections>
     49                    </menuItem>
     50                    <menuItem isSeparatorItem="YES" id="xT4-H9-l6g"/>
     51                    <menuItem title="Preferences…" keyEquivalent="," id="2Kn-gO-qBP">
     52                        <connections>
     53                            <action selector="handleNativePreferencesClicked:" target="-1" id="wIn-2L-u1k"/>
     54                        </connections>
     55                    </menuItem>
     56                    <menuItem isSeparatorItem="YES" id="45f-s8-MiT"/>
     57                    <menuItem title="Services" id="x2v-WG-Nuy">
     58                        <modifierMask key="keyEquivalentModifierMask"/>
     59                        <menu key="submenu" title="Services" systemMenu="services" id="DkL-DH-gJf"/>
     60                    </menuItem>
     61                    <menuItem isSeparatorItem="YES" id="T1H-h7-Sat"/>
     62                    <menuItem title="Hide Application" keyEquivalent="h" id="uAA-NV-src">
     63                        <connections>
     64                            <action selector="hide:" target="-1" id="wFN-Nz-FpI"/>
     65                        </connections>
     66                    </menuItem>
     67                    <menuItem title="Hide Others" keyEquivalent="h" id="ext-76-4lm">
     68                        <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
     69                        <connections>
     70                            <action selector="hideOtherApplications:" target="-1" id="KyT-0x-vod"/>
     71                        </connections>
     72                    </menuItem>
     73                    <menuItem title="Show All" id="HmI-6K-eUt">
     74                        <modifierMask key="keyEquivalentModifierMask"/>
     75                        <connections>
     76                            <action selector="unhideAllApplications:" target="-1" id="mXg-9c-azx"/>
     77                        </connections>
     78                    </menuItem>
     79                    <menuItem isSeparatorItem="YES" id="xOX-eV-fcA"/>
     80                    <menuItem title="Quit Application" keyEquivalent="q" id="Fap-30-HH0">
     81                        <connections>
     82                            <action selector="terminate:" target="-1" id="IM7-XC-JlF"/>
     83                        </connections>
     84                    </menuItem>
     85                </items>
     86            </menu>
     87        </menuItem>
    4088    </objects>
    4189</document>
  • launchers/macosx/I2PLauncher/Preferences.storyboard

    r5d389c8 re36a3b3  
    6868                                <rect key="frame" x="18" y="198" width="325" height="26"/>
    6969                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
    70                                 <buttonCell key="cell" type="check" title="Start the I2P Launcher at User login (Mac startup)" bezelStyle="regularSquare" imagePosition="left" enabled="NO" inset="2" id="EOY-1C-aqa">
     70                                <buttonCell key="cell" type="check" title="Start the I2P Launcher at User login (Mac startup)" bezelStyle="regularSquare" imagePosition="left" inset="2" id="EOY-1C-aqa">
    7171                                    <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
    7272                                    <font key="font" metaFont="system"/>
     
    133133                                <rect key="frame" x="18" y="173" width="313" height="23"/>
    134134                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
    135                                 <buttonCell key="cell" type="check" title="Start Firefox with a I2P enabled profile at launch" bezelStyle="regularSquare" imagePosition="left" enabled="NO" state="on" inset="2" id="i7v-mQ-d1Y">
     135                                <buttonCell key="cell" type="check" title="Start Firefox with a I2P enabled profile at launch" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="i7v-mQ-d1Y">
    136136                                    <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
    137137                                    <font key="font" metaFont="system"/>
     
    219219                                <rect key="frame" x="18" y="345" width="257" height="28"/>
    220220                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
    221                                 <buttonCell key="cell" type="check" title="Yes, I want to edit advanced settings" bezelStyle="regularSquare" imagePosition="left" enabled="NO" inset="2" id="UzU-4G-MLw">
     221                                <buttonCell key="cell" type="check" title="Yes, I want to edit advanced settings" bezelStyle="regularSquare" imagePosition="left" inset="2" id="UzU-4G-MLw">
    222222                                    <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
    223223                                    <font key="font" metaFont="system"/>
     
    244244                                    <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
    245245                                    <subviews>
    246                                         <tableView identifier="AdvancedView" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" headerView="M6Y-Yi-YWr" viewBased="YES" id="lzO-OC-oiQ" customClass="AdvancedTableView" customModule="I2PLauncher" customModuleProvider="target">
     246                                        <tableView identifier="AdvancedView" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" headerView="M6Y-Yi-YWr" viewBased="YES" id="lzO-OC-oiQ" customClass="AdvancedTableView" customModule="I2PLauncher" customModuleProvider="target">
    247247                                            <rect key="frame" x="0.0" y="0.0" width="645" height="285"/>
    248248                                            <autoresizingMask key="autoresizingMask"/>
     
    251251                                            <color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
    252252                                            <tableColumns>
    253                                                 <tableColumn identifier="KeyColumnID" width="116" minWidth="40" maxWidth="1000" id="3Hj-6J-5ww">
     253                                                <tableColumn identifier="KeyColumnID" editable="NO" width="116" minWidth="40" maxWidth="1000" id="3Hj-6J-5ww">
    254254                                                    <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Key">
    255255                                                        <font key="font" metaFont="smallSystem"/>
     
    284284                                                    </prototypeCellViews>
    285285                                                </tableColumn>
    286                                                 <tableColumn identifier="DefaultColumnID" width="120" minWidth="40" maxWidth="1000" id="xna-T0-L5h">
     286                                                <tableColumn identifier="DefaultColumnID" editable="NO" width="120" minWidth="40" maxWidth="1000" id="xna-T0-L5h">
    287287                                                    <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Default Value">
    288288                                                        <font key="font" metaFont="smallSystem"/>
     
    337337                                                                    <rect key="frame" x="0.0" y="0.0" width="400" height="17"/>
    338338                                                                    <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
    339                                                                     <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="Sj7-Se-KMC">
     339                                                                    <textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" title="Table View Cell" usesSingleLineMode="YES" id="Sj7-Se-KMC">
    340340                                                                        <font key="font" metaFont="system"/>
    341341                                                                        <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
    342342                                                                        <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
    343343                                                                    </textFieldCell>
     344                                                                    <connections>
     345                                                                        <action selector="onEnterInTextField:" target="mVJ-sm-WjL" id="4y0-HJ-teb"/>
     346                                                                    </connections>
    344347                                                                </textField>
    345348                                                            </subviews>
  • launchers/macosx/I2PLauncher/SwiftMainDelegate.swift

    r5d389c8 re36a3b3  
    3333  let sharedRouterMgmr = RouterManager.shared()
    3434 
     35  // Constructor, think of it like an early entrypoint.
    3536  override init() {
    3637    super.init()
     38   
    3739    if (!DetectJava.shared().isJavaFound()) {
    3840    DetectJava.shared().findIt()
     
    5658  } // End of init()
    5759 
     60  // A function which detects the current installed I2P router version
    5861  @objc func findInstalledI2PVersion() {
    5962    var i2pPath = Preferences.shared().i2pBaseDirectory
     
    8588  }
    8689 
     90 
     91  // Helper functions for the optional dock icon
    8792  func triggerDockIconShowHide(showIcon state: Bool) -> Bool {
    8893    var result: Bool
     
    95100  }
    96101 
     102  // Helper functions for the optional dock icon
    97103  func getDockIconStateIsShowing() -> Bool {
    98104    if NSApp.activationPolicy() == NSApplicationActivationPolicy.regular {
     
    103109  }
    104110 
     111  /**
     112   *
     113   * This is the swift "entrypoint". In C it would been "main(argc,argv)"
     114   *
     115   */
    105116  @objc func applicationDidFinishLaunching() {
    106117    switch Preferences.shared().showAsIconMode {
     
    122133      DistributedNotificationCenter.default().post(name: .killLauncher, object: Bundle.main.bundleIdentifier!)
    123134    }
     135   
     136    if (Preferences.shared().alsoStartFirefoxOnLaunch)
     137    {
     138      // TODO: For some reason it does not seem to obay the two minutes delay.
     139      // If set, execute i2p browser / firefox after two minutes.
     140      DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
     141        FirefoxManager.shared().executeFirefox()
     142      }
     143    }
    124144  }
    125145 
     
    137157  }
    138158 
     159  /**
     160   *
     161   * This function will execute when the launcher shuts down for some reason.
     162   * Could be either OS or user triggered.
     163   *
     164   */
    139165  @objc func applicationWillTerminate() {
    140166    // Shutdown stuff
  • launchers/macosx/I2PLauncher/Utils/Preferences.swift

    r5d389c8 re36a3b3  
    117117    defaults["I2Pref_allowAdvancedPreferences"] = false
    118118    defaults["I2Pref_alsoStartFirefoxOnLaunch"] = true
    119     defaults["I2Pref_firefoxBundlePath"] = "/Applications/Firefox.app"
     119    defaults["I2Pref_useServiceManagementAsStartupTool"] = false
    120120    defaults["I2Pref_firefoxProfilePath"] = NSString(format: "%@/Library/Application Support/i2p/profile", home)
    121121    defaults["I2Pref_consolePortCheckNum"] = 7657
  • launchers/macosx/I2PLauncher/Utils/Startup.swift

    r5d389c8 re36a3b3  
    99import Foundation
    1010
    11 class Startup {
     11class Startup : NSObject {
     12 
     13  let loginItemsList : LSSharedFileList = LSSharedFileListCreate(nil, kLSSharedFileListSessionLoginItems.takeRetainedValue(), nil).takeRetainedValue();
    1214 
    1315 
    14   /*
    15   func applicationIsInStartUpItems() -> Bool {
    16     return itemReferencesInLoginItems().existingReference != nil
     16 
     17  func addLoginItem(_ path: CFURL) -> Bool {
     18   
     19    if(getLoginItem(path) != nil) {
     20      print("Login Item has already been added to the list.");
     21      return true;
     22    }
     23   
     24    var path : CFURL = CFURLCreateWithString(nil, Bundle.main.bundleURL.absoluteString as CFString, nil);
     25    print("Path adding to Login Item list is: ", path);
     26   
     27    // add new Login Item at the end of Login Items list
     28    if let loginItem = LSSharedFileListInsertItemURL(loginItemsList,
     29                                                     getLastLoginItemInList(),
     30                                                     nil, nil,
     31                                                     path,
     32                                                     nil, nil) {
     33      print("Added login item is: ", loginItem);
     34      return true;
     35    }
     36   
     37    return false;
    1738  }
    1839 
    19   func toggleLaunchAtStartup() {
    20     let itemReferences = itemReferencesInLoginItems()
    21     let shouldBeToggled = (itemReferences.existingReference == nil)
    22     let loginItemsRef = LSSharedFileListCreate(
    23       nil,
    24       kLSSharedFileListSessionLoginItems.takeRetainedValue(),
    25       nil
    26       ).takeRetainedValue() as LSSharedFileList?
     40 
     41  func removeLoginItem(_ path: CFURL) -> Bool {
    2742   
    28     if loginItemsRef != nil {
    29       if shouldBeToggled {
    30         if let appUrl: CFURL = NSURL.fileURLWithPath(Bundle.mainBundle().bundlePath) {
    31           LSSharedFileListInsertItemURL(loginItemsRef, itemReferences.lastReference, nil, nil, appUrl, nil, nil)
    32           print("Application was added to login items")
    33         }
    34       } else {
    35         if let itemRef = itemReferences.existingReference {
    36           LSSharedFileListItemRemove(loginItemsRef,itemRef);
    37           print("Application was removed from login items")
    38         }
     43    // remove Login Item from the Login Items list
     44    if let oldLoginItem = getLoginItem(path) {
     45      print("Old login item is: ", oldLoginItem);
     46      if(LSSharedFileListItemRemove(loginItemsList, oldLoginItem) == noErr) {
     47        return true;
    3948      }
     49      return false;
    4050    }
     51    print("Login Item for given path not found in the list.");
     52    return true;
    4153  }
    4254 
    43   func itemReferencesInLoginItems() -> (existingReference: LSSharedFileListItem?, lastReference: LSSharedFileListItem?) {
    44     var itemUrl = UnsafeMutablePointer<Unmanaged<CFURL>?>.allocate(capacity: 1)
     55 
     56  func getLoginItem(_ path : CFURL) -> LSSharedFileListItem! {
    4557   
    46     let appUrl = NSURL.fileURL(withPath: Bundle.main.bundlePath)
    47     if !appUrl.absoluteString.isEmpty {
    48       let loginItemsRef = LSSharedFileListCreate(
    49         nil,
    50         kLSSharedFileListSessionLoginItems.takeRetainedValue(),
    51         nil
    52         ).takeRetainedValue() as LSSharedFileList?
     58    var path : CFURL = CFURLCreateWithString(nil, Bundle.main.bundleURL.absoluteString as CFString, nil);
     59   
     60   
     61    // Copy all login items in the list
     62    let loginItems : NSArray = LSSharedFileListCopySnapshot(loginItemsList, nil).takeRetainedValue();
     63   
     64    var foundLoginItem : LSSharedFileListItem?;
     65    var nextItemUrl : Unmanaged<CFURL>?;
     66   
     67    // Iterate through login items to find one for given path
     68    print("App URL: ", path);
     69    for var i in (0..<loginItems.count)  // CFArrayGetCount(loginItems)
     70    {
    5371     
    54       if loginItemsRef != nil {
    55         let loginItems = LSSharedFileListCopySnapshot(loginItemsRef, nil).takeRetainedValue() as NSArray
    56         print("There are \(loginItems.count) login items")
     72      var nextLoginItem : LSSharedFileListItem = loginItems.object(at: i) as! LSSharedFileListItem; // CFArrayGetValueAtIndex(loginItems, i).;
     73     
     74     
     75      if(LSSharedFileListItemResolve(nextLoginItem, 0, &nextItemUrl, nil) == noErr) {
    5776       
    58         if(loginItems.count > 0) {
    59           let lastItemRef = loginItems.lastObject as! LSSharedFileListItem
    60          
    61           for var currentItem in loginItems {
    62             let currentItemRef = currentItem as! LSSharedFileListItem
    63            
    64             let urlRef: CFURL = LSSharedFileListItemCopyResolvedURL(currentItemRef, 0, nil) as! CFURL
    65             let url = urlRef.takeUnretainedValue()
    66             if !urlRef?.isEmpty {
    67               print("URL Ref: \(urlRef.lastPathComponent)")
    68               if urlRef.isEqual(appUrl) {
    69                 return (currentItemRef, lastItemRef)
    70               }
    71             }
    72             else {
    73               print("Unknown login application")
    74             }
    75           }
    76           // The application was not found in the startup list
    77           return (nil, lastItemRef)
    78          
    79         } else  {
    80           let addatstart: LSSharedFileListItem = kLSSharedFileListItemBeforeFirst.takeRetainedValue()
    81           return(nil,addatstart)
     77       
     78       
     79        print("Next login item URL: ", nextItemUrl!.takeUnretainedValue());
     80        // compare searched item URL passed in argument with next item URL
     81        if(nextItemUrl!.takeRetainedValue() == path) {
     82          foundLoginItem = nextLoginItem;
    8283        }
    8384      }
    8485    }
    8586   
    86     return (nil, nil)
    87   }*/
     87    return foundLoginItem;
     88  }
     89 
     90  func getLastLoginItemInList() -> LSSharedFileListItem! {
     91   
     92    // Copy all login items in the list
     93    let loginItems : NSArray = LSSharedFileListCopySnapshot(loginItemsList, nil).takeRetainedValue() as NSArray;
     94    if(loginItems.count > 0) {
     95      let lastLoginItem = loginItems.lastObject as! LSSharedFileListItem;
     96     
     97      print("Last login item is: ", lastLoginItem);
     98      return lastLoginItem
     99    }
     100   
     101    return kLSSharedFileListItemBeforeFirst.takeRetainedValue();
     102  }
     103 
     104  func isLoginItemInList(_ path : CFURL) -> Bool {
     105   
     106    if(getLoginItem(path) != nil) {
     107      return true;
     108    }
     109   
     110    return false;
     111  }
     112 
     113  static func appPath() -> CFURL {
     114   
     115    return NSURL.fileURL(withPath: Bundle.main.bundlePath) as CFURL;
     116  }
     117 
    88118}
  • launchers/macosx/I2PLauncher/Utils/browser/FirefoxManager.swift

    r5d389c8 re36a3b3  
    3030  }
    3131 
     32  // Since we execute in the "unix/POSIX way", we need the full path of the binary.
    3233  func bundleExecutableSuffixPath() -> String {
    3334    return "/Contents/MacOS/firefox"
     
    4344  }
    4445
     46  /**
     47   *
     48   * First, try find I2P Browser, if  it fails, then try Firefox or Firefox Developer.
     49   *
     50   * Instead of using hardcoded paths, or file search we use OS X's internal "registry" API
     51   * and detects I2P Browser or Firefox by bundle name. (or id, but name is more readable)
     52   *
     53   */
    4554  func tryAutoDetect() -> Bool {
    46     let expectedPath = Preferences.shared()["I2Pref_firefoxBundlePath"] as! String
     55    var browserPath = NSWorkspace.shared().fullPath(forApplication: "I2P Browser")
     56    if (browserPath == nil)
     57    {
     58      browserPath = NSWorkspace.shared().fullPath(forApplication: "Firefox")
     59      if (browserPath == nil)
     60      {
     61        browserPath = NSWorkspace.shared().fullPath(forApplication: "Firefox Developer")
     62      }
     63    }
    4764   
    4865    self.isFirefoxProfileExtracted = directoryExistsAtPath(Preferences.shared()["I2Pref_firefoxProfilePath"] as! String)
    4966   
    50     let result = directoryExistsAtPath(expectedPath)
     67    // If browserPath is still nil, then nothing above was found and we can return early.
     68    if (browserPath == nil)
     69    {
     70      return false
     71    }
     72   
     73    let result = directoryExistsAtPath(browserPath!)
    5174    self.isFirefoxFound = result
    5275    if (result) {
    53       self.firefoxAppPath = expectedPath
     76      self.firefoxAppPath = browserPath!
    5477      return true
    5578    }
  • launchers/macosx/I2PLauncher/routermgmt/RouterProcessStatus+ObjectiveC.swift

    r5d389c8 re36a3b3  
    1111extension RouterProcessStatus {
    1212 
    13   static func createNewRouterProcess(i2pPath: String) {
    14     let timeWhenStarted = Date()
    15     RouterProcessStatus.routerStartedAt = timeWhenStarted
    16     SBridge.sharedInstance().startupI2PRouter(i2pPath)
    17     RouterManager.shared().updateState()
    18   }
    19   static func shutdownRouterChildProcess() {
    20     RouterManager.shared().getRouterTask()?.requestShutdown()
    21     RouterManager.shared().updateState()
    22   }
    2313}
  • launchers/macosx/I2PLauncher/userinterface/RouterStatusView.swift

    r5d389c8 re36a3b3  
    4040  @objc func actionBtnStartRouter(_ sender: Any?) {
    4141    NSLog("Router start clicked")
    42     /*if (RouterManager.shared().getRouterTask() == nil) {
    43       SBridge.sharedInstance().startupI2PRouter(RouterProcessStatus.i2pDirectoryPath)
    44     }*/
    4542    (sender as! NSButton).isTransparent = true
    4643    let routerStatus = RouterRunner.launchAgent?.status()
  • launchers/macosx/I2PLauncher/userinterface/StatusBarController.swift

    r5d389c8 re36a3b3  
    2222  @IBOutlet var routerStatusTabView: RouterStatusView?
    2323 
     24  @IBAction func handleNativePreferencesClicked(_ sender: Any) {
     25    StatusBarController.launchPreferences(sender)
     26  }
    2427  //var updateObjectRef : SUUpdater?
    2528 
  • launchers/macosx/I2PLauncher/userinterface/preferences/PreferencesViewController+TableView.swift

    r5d389c8 re36a3b3  
    2626 
    2727  func tableViewDoubleClick(_ sender:AnyObject) {
    28    
     28    print("Double click")
    2929    // 1
    30     /*guard tableView.selectedRow >= 0,
    31      let item = Preferences.shared()[tableView.selectedRow] else {
    32      return
    33      }
    34      
     30    print(self.advPrefTableView.selectedRow)
     31    guard self.advPrefTableView.selectedRow >= 0,
     32      let item = Preferences.shared()[self.advPrefTableView.selectedRow] else {
     33        return
     34    }
     35    print(item.name)
     36     /*
    3537     if item.isFolder {
    3638     // 2
     
    4648  func tableView(_ tableView: NSTableView, sortDescriptorsDidChange oldDescriptors: [NSSortDescriptor]) {
    4749    // 1
    48     guard let sortDescriptor = tableView.sortDescriptors.first else {
     50    guard let sortDescriptor = self.advPrefTableView.sortDescriptors.first else {
    4951      return
    5052    }
     
    7577      cellIdentifier = CellIdentifiers.NameCell
    7678    } else if tableColumn == tableView.tableColumns[1] {
    77       text = "\(item.defaultValue!)"
     79      text = "\(item.defaultValue ?? "")"
    7880      cellIdentifier = CellIdentifiers.DefaultCell
    7981    } else if tableColumn == tableView.tableColumns[2] {
  • launchers/macosx/I2PLauncher/userinterface/preferences/PreferencesViewController.swift

    r5d389c8 re36a3b3  
    3939  @IBOutlet var buttonResetRouterConfig: NSButton?
    4040 
     41  @IBAction func onEnterInTextField(_ sender: NSTextField) {
     42    let selectedRowNumber = advPrefTableView.selectedRow
     43    print("Trying to store preferences")
     44    let currentItem = Preferences.shared()[selectedRowNumber]
     45    currentItem?.selectedValue = sender.stringValue
     46    Preferences.shared()[selectedRowNumber] = currentItem
     47    UserDefaults.standard.set(sender.stringValue, forKey: (currentItem?.name)!)
     48    Preferences.shared().syncPref()
     49  }
    4150 
    4251  override func viewDidLoad() {
     
    6170      advPrefTableView.tableColumns[1].sortDescriptorPrototype = NSSortDescriptor(key: "defaultValue", ascending: true)
    6271      advPrefTableView.tableColumns[2].sortDescriptorPrototype = NSSortDescriptor(key: "selectedValue", ascending: true)
     72     
     73      self.advPrefTableView.isEnabled = Preferences.shared().allowAdvancedPreferenceEdit
    6374    }
    6475   
     
    125136  @IBAction func checkboxStartLauncherOnOSXStartupClicked(_ sender: NSButton) {
    126137    let launcherAppId = "net.i2p.bootstrap.macosx.StartupItemApp"
     138    let startupMgr = Startup()
    127139    switch sender.state {
    128140    case NSOnState:
    129141      print("on")
    130142      Preferences.shared()["I2Pref_startLauncherAtLogin"] = true
    131       let success = SMLoginItemSetEnabled(launcherAppId as CFString, true)
    132       print("SMLoginItemSetEnabled returned \(success)....")
     143      if (Preferences.shared()["I2Pref_useServiceManagementAsStartupTool"] as! Bool)
     144      {
     145        let success = SMLoginItemSetEnabled(launcherAppId as CFString, true)
     146        print("SMLoginItemSetEnabled returned \(success)....")
     147      } else {
     148        startupMgr.addLoginItem(Startup.appPath())
     149        print("Shared file for auto-startup added. (viewable via OSX Preferences -> Users -> Login Items)")
     150      }
    133151    case NSOffState:
    134152      print("off")
    135153      Preferences.shared()["I2Pref_startLauncherAtLogin"] = false
    136       let success = SMLoginItemSetEnabled(launcherAppId as CFString, false)
    137       print("SMLoginItemSetEnabled returned \(success)....")
     154      if (Preferences.shared()["I2Pref_useServiceManagementAsStartupTool"] as! Bool)
     155      {
     156        let success = SMLoginItemSetEnabled(launcherAppId as CFString, false)
     157        print("SMLoginItemSetEnabled returned \(success)....")
     158      } else {
     159        startupMgr.removeLoginItem(Startup.appPath())
     160        print("Shared file for auto-startup removed (if any). (viewable via OSX Preferences -> Users -> Login Items)")
     161      }
    138162    case NSMixedState:
    139163      print("mixed")
     
    144168    switch sender.state {
    145169    case NSOnState:
    146       print("on")
    147     case NSOffState:
    148       print("off")
     170      print("launch firefox: on")
     171      Preferences.shared().alsoStartFirefoxOnLaunch = true
     172    case NSOffState:
     173      print("launch firefox: off")
     174      Preferences.shared().alsoStartFirefoxOnLaunch = false
    149175    case NSMixedState:
    150176      print("mixed")
     
    262288      print("on")
    263289      Preferences.shared().allowAdvancedPreferenceEdit = true
     290      self.advPrefTableView.isEnabled = true
    264291    case NSOffState:
    265292      print("off")
    266293      Preferences.shared().allowAdvancedPreferenceEdit = false
     294      self.advPrefTableView.isEnabled = false
    267295    case NSMixedState:
    268296      print("mixed")
  • launchers/macosx/SBridge.h

    r5d389c8 re36a3b3  
    1919#include <vector>
    2020#include "include/fn.h"
    21 //std::future<int> startupRouter(NSString* javaBin, NSArray<NSString*>* arguments, NSString* i2pBaseDir, RouterProcessStatus* routerStatus = nil);
    22 
    2321
    2422namespace osx {
     
    5957@interface SBridge : NSObject
    6058@property (nonatomic, assign) I2PRouterTask* currentRouterInstance;
    61 - (NSString*) buildClassPath:(NSString*)i2pPath;
    62 - (void) startupI2PRouter:(NSString*)i2pRootPath;
    6359- (void) openUrl:(NSString*)url;
    6460+ (void) logProxy:(int)level formattedMsg:(NSString*)formattedMsg;
  • launchers/macosx/SBridge.mm

    r5d389c8 re36a3b3  
    2929
    3030
    31 
    32 std::future<int> startupRouter(NSString* javaBin, NSArray<NSString*>* arguments, NSString* i2pBaseDir, RouterProcessStatus* routerStatus) {
    33   @try {
    34    
    35     /**
    36      *
    37      * The following code will do a test, where it lists all known processes in the OS (visibility depending on user rights)
    38      * and scan for any command/arguments matching the substring "i2p.jar" - and in which case it won't start I2P itself.
    39      *
    40      **/
    41     IIProcessInfo* processInfoObj = [[IIProcessInfo alloc] init];
    42     [processInfoObj obtainFreshProcessList];
    43     auto anyRouterLookingProcs = [processInfoObj findProcessWithStringInNameOrArguments:@"i2p.jar"];
    44     if (anyRouterLookingProcs) {
    45       /**
    46        * The router was found running
    47        */
    48       auto errMessage = @"Seems i2p is already running - I've detected another process with i2p.jar in it's arguments.";
    49       MLog(4, @"%@", errMessage);
    50       sendUserNotification(APP_IDSTR, errMessage);
    51       [routerStatus triggerEventWithEn:@"router_already_running" details:@"won't start - another router is running"];
    52       return std::async(std::launch::async, []{
    53         return -1;
    54       });
    55     } else {
    56       /**
    57        * No router was detected running
    58        **/
    59       RTaskOptions* options = [RTaskOptions alloc];
    60       options.binPath = javaBin;
    61       options.arguments = arguments;
    62       options.i2pBaseDir = i2pBaseDir;
    63       auto instance = [[I2PRouterTask alloc] initWithOptions: options];
    64      
    65       [[SBridge sharedInstance] setCurrentRouterInstance:instance];
    66       [instance execute];
    67       sendUserNotification(APP_IDSTR, @"The I2P router is starting up.");
    68       auto pid = [instance getPID];
    69       MLog(2, @"Got pid: %d", pid);
    70       if (routerStatus != nil) {
    71         // TODO: Merge events router_start and router_pid ?
    72         [routerStatus triggerEventWithEn:@"router_start" details:@"normal start"];
    73         [routerStatus triggerEventWithEn:@"router_pid" details:[NSString stringWithFormat:@"%d", pid]];
    74       }
    75       NSString *applicationSupportDirectory = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) firstObject];
    76       auto pidFile = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/i2p/router.pid", applicationSupportDirectory]];
    77       NSError *err;
    78      
    79       if (![[NSString stringWithFormat:@"%d", pid] writeToURL:pidFile atomically:YES encoding:NSUTF8StringEncoding error:&err]) {
    80         MLog(4, @"Error; %@", err);
    81       } else {
    82         MLog(3, @"Wrote pid file to %@", pidFile);
    83       }
    84      
    85       return std::async(std::launch::async, [&pid]{
    86         return pid;
    87       });
    88     }
    89   }
    90   @catch (NSException *e)
    91   {
    92     auto errStr = [NSString stringWithFormat:@"Expection occurred %@",[e reason]];
    93     MLog(4, @"%@", errStr);
    94     sendUserNotification(APP_IDSTR, errStr);
    95     [[SBridge sharedInstance] setCurrentRouterInstance:nil];
    96    
    97     if (routerStatus != nil) {
    98       [routerStatus triggerEventWithEn:@"router_exception" details:errStr];
    99     }
    100    
    101     return std::async(std::launch::async, [&]{
    102       return 0;
    103     });
    104   }
    105 }
    106 
    107 
    108 
    10931@implementation SBridge
    11032
     
    13052}
    13153
    132 - (NSString*) buildClassPath:(NSString*)i2pPath
    133 {
    134   const char * basePath = [i2pPath UTF8String];
    135   auto jarList = buildClassPathForObjC(basePath);
    136   const char * classpath = jarList.c_str();
    137   MLog(0, @"Classpath from ObjC = %s", classpath);
    138   return [[NSString alloc] initWithUTF8String:classpath];
    139 }
    140 
    14154+ (void) logProxy:(int)level formattedMsg:(NSString*)formattedMsg
    14255{
     
    14457}
    14558
    146 
    147 - (void)startupI2PRouter:(NSString*)i2pRootPath
    148 {
    149   std::string basePath([i2pRootPath UTF8String]);
    150  
    151   auto classPathStr = buildClassPathForObjC(basePath);
    152  
    153   RouterProcessStatus* routerStatus = [[RouterProcessStatus alloc] init];
    154  
    155   NSString *confDir = [NSString stringWithFormat:@"%@/Library/Application\\ Support/i2p", NSHomeDirectory()];
    156  
    157   try {
    158     std::vector<NSString*> argList = {
    159       @"-v",
    160       @"1.7+",
    161       @"--exec",
    162       @"java",
    163       @"-Xmx512M",
    164       @"-Xms128m",
    165       @"-Djava.awt.headless=true",
    166       [NSString stringWithFormat:@"-Dwrapper.logfile=%@/router.log", [NSString stringWithUTF8String:getDefaultLogDir().c_str()]],
    167       @"-Dwrapper.logfile.loglevel=DEBUG",
    168       [NSString stringWithFormat:@"-Dwrapper.java.pidfile=%@/router.pid", confDir],
    169       @"-Dwrapper.console.loglevel=DEBUG"
    170     };
    171    
    172     std::string baseDirArg("-Di2p.dir.base=");
    173     baseDirArg += basePath;
    174     std::string javaLibArg("-Djava.library.path=");
    175     javaLibArg += basePath;
    176     // TODO: pass this to JVM
    177     //auto java_opts = getenv("JAVA_OPTS");
    178    
    179     std::string cpString = std::string("-cp");
    180    
    181     argList.push_back([NSString stringWithUTF8String:baseDirArg.c_str()]);
    182     argList.push_back([NSString stringWithUTF8String:javaLibArg.c_str()]);
    183     argList.push_back([NSString stringWithUTF8String:cpString.c_str()]);
    184     argList.push_back([NSString stringWithUTF8String:classPathStr.c_str()]);
    185     argList.push_back(@"net.i2p.router.Router");
    186     auto javaBin = std::string("/usr/libexec/java_home");
    187    
    188    
    189     sendUserNotification(APP_IDSTR, @"I2P Router is starting up!");
    190     auto nsJavaBin = [NSString stringWithUTF8String:javaBin.c_str()];
    191     auto nsBasePath = i2pRootPath;
    192     NSArray* arrArguments = [NSArray arrayWithObjects:&argList[0] count:argList.size()];
    193    
    194     MLog(0, @"Trying to run command: %@", nsJavaBin);
    195     MLog(0, @"With I2P Base dir: %@", i2pRootPath);
    196     MLog(0, @"And Arguments: %@", arrArguments);
    197     startupRouter(nsJavaBin, arrArguments, nsBasePath, routerStatus);
    198   } catch (std::exception &err) {
    199     auto errMsg = [NSString stringWithUTF8String:err.what()];
    200     MLog(4, @"Exception: %@", errMsg);
    201     sendUserNotification(APP_IDSTR, [NSString stringWithFormat:@"Error: %@", errMsg]);
    202     [routerStatus setRouterStatus: false];
    203     [routerStatus setRouterRanByUs: false];
    204     [routerStatus triggerEventWithEn:@"router_exception" details:[NSString stringWithFormat:@"Error: %@", errMsg]];
    205   }
    206 }
    20759@end
    20860
  • launchers/macosx/main.mm

    r5d389c8 re36a3b3  
    7070}
    7171
    72 - (void)setApplicationDefaultPreferences {
    73   [self.userPreferences registerDefaults:@{
    74     @"enableLogging": @YES,
    75     @"enableVerboseLogging": @YES,
    76     @"autoStartRouterAtBoot": @NO,
    77     @"startLauncherAtLogin": @NO,
    78     @"startRouterAtStartup": @YES,
    79     @"stopRouterAtShutdown": @YES,
    80     @"letRouterLiveEvenLauncherDied": @NO,
    81     @"consolePortCheckNum": @7657,
    82     @"i2pBaseDirectory": (NSString *)CFStringCreateWithCString(NULL, const_cast<const char *>(getDefaultBaseDir().c_str()), kCFStringEncodingUTF8)
    83   }];
    84 
    85   auto dict = [self.userPreferences dictionaryRepresentation];
    86   [self.userPreferences setPersistentDomain:dict forName:NSAPPDOMAIN];
    87 
    88   CFPreferencesSetMultiple((CFDictionaryRef)dict, NULL, CFAPPDOMAIN, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
    89   CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
    90 
    91   NSLog(@"Default preferences stored!");
    92 }
    93 
    94 
    9572- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    9673  // Init application here
     
    10481  // Start with user preferences
    10582  self.userPreferences = [NSUserDefaults standardUserDefaults];
    106   [self setApplicationDefaultPreferences];
    107   self.enableLogging = [self.userPreferences boolForKey:@"enableLogging"];
    108   self.enableVerboseLogging = [self.userPreferences boolForKey:@"enableVerboseLogging"];
    10983  // In case we are unbundled, make us a proper UI application
    11084  [NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];
Note: See TracChangeset for help on using the changeset viewer.