Making a Checkbox Toggle The Dock Icon On and Off
Asked Answered
L

5

11

How would I make a checkbox hide the dock icon if it was checked? I have made a checkbox toggle a menubar item but how would you do it with the dock icon? Looking for some code to do this. Thanks!

Lucchesi answered 4/7, 2009 at 15:10 Comment(1)
See my comment to similar SO question: https://mcmap.net/q/235042/-how-to-hide-the-dock-icon. Tested and works on macOS 11.Idun
C
9

i've use this code:

BOOL iconInDock = [[NSUserDefaults standardUserDefaults] boolForKey:smHideShowIcon];
if (iconInDock) {
    ProcessSerialNumber psn = { 0, kCurrentProcess };
    // display dock icon
    TransformProcessType(&psn, kProcessTransformToForegroundApplication);
}

ok, it's work for my application if I to set LSUIElement=1 in the Info.plist. That's code works only for show, but how I can hide icon?

Curitiba answered 16/7, 2009 at 0:32 Comment(9)
Isn't that exactly the same as the Code in the other answer?Lucchesi
Why am I getting those errors even when I have imported the frameworks?Lucchesi
pupsor.com/wp-content/uploads/2009/07/Joshua.zip it's archive of project with example working showing. Try that and send resultCuritiba
Thanks! I've got that to work although when my Application is LSUIElement there is no way to get to the preferences window to change the settings so people can make it a normal app, this is because it is never in the menubar, it always has the name of another application. How would I get it to show the Menubar so people can actually change the app back to a normal app? For example. snapplr.com/93mm The App is the window in the bottom corner it's selected but it's still showing Finder as the selected app. Also whats odd since i entered this code I can't type 'a' when the app is open.Lucchesi
yea, i see. add this code after TransformProcessType... it works ;) // switch to Dock.app [[NSWorkspace sharedWorkspace] launchAppWithBundleIdentifier:@"com.apple.dock" options:NSWorkspaceLaunchDefault additionalEventParamDescriptor:nil launchIdentifier:nil]; // switch back [[NSApplication sharedApplication] activateIgnoringOtherApps:TRUE];Curitiba
Thanks, I just added that in but it doesn't seem to change anything, Do you know why?Lucchesi
Hmmm, i've just checked it - it works. New version of joshua_1.1.zip there pupsor.com/wp-content/uploads/2009/07/joshua_1.1.zip check this and make answer. does it work for you?Curitiba
Just checked it and it still doesn't work, I know why because on the second sample project you sent me it wasn't set as LSUIElement. When it is in mine and the first project you sent me.Lucchesi
Make sure at your end on the new test app you sent it is set as LSUIElement, if it is when the App is launched there will be no dock icon, the show button should work and you won't see the apps name in the Menubar. If it is not LSUIElement everything will work like a normal app and the Show button will do nothing.Lucchesi
S
12

Update for Swift, use both ways has been presented above (they give the same result):

public class func toggleDockIcon_Way1(showIcon state: Bool) -> Bool {
    // Get transform state.
    var transformState: ProcessApplicationTransformState
    if state {
        transformState = ProcessApplicationTransformState(kProcessTransformToForegroundApplication)
    }
    else {
        transformState = ProcessApplicationTransformState(kProcessTransformToUIElementApplication)
    }

    // Show / hide dock icon.
    var psn = ProcessSerialNumber(highLongOfPSN: 0, lowLongOfPSN: UInt32(kCurrentProcess))
    let transformStatus: OSStatus = TransformProcessType(&psn, transformState)
    return transformStatus == 0
}

public class func toggleDockIcon_Way2(showIcon state: Bool) -> Bool {
    var result: Bool
    if state {
        result = NSApp.setActivationPolicy(NSApplicationActivationPolicy.Regular)
    }
    else {
        result = NSApp.setActivationPolicy(NSApplicationActivationPolicy.Accessory)
    }
    return result
}
Saratov answered 9/10, 2014 at 17:8 Comment(1)
Hiding the icon with this methods hides the app itself too. I have a timer which makes it appear again (without menu) but this is just bad UXFootstalk
C
9

i've use this code:

BOOL iconInDock = [[NSUserDefaults standardUserDefaults] boolForKey:smHideShowIcon];
if (iconInDock) {
    ProcessSerialNumber psn = { 0, kCurrentProcess };
    // display dock icon
    TransformProcessType(&psn, kProcessTransformToForegroundApplication);
}

ok, it's work for my application if I to set LSUIElement=1 in the Info.plist. That's code works only for show, but how I can hide icon?

Curitiba answered 16/7, 2009 at 0:32 Comment(9)
Isn't that exactly the same as the Code in the other answer?Lucchesi
Why am I getting those errors even when I have imported the frameworks?Lucchesi
pupsor.com/wp-content/uploads/2009/07/Joshua.zip it's archive of project with example working showing. Try that and send resultCuritiba
Thanks! I've got that to work although when my Application is LSUIElement there is no way to get to the preferences window to change the settings so people can make it a normal app, this is because it is never in the menubar, it always has the name of another application. How would I get it to show the Menubar so people can actually change the app back to a normal app? For example. snapplr.com/93mm The App is the window in the bottom corner it's selected but it's still showing Finder as the selected app. Also whats odd since i entered this code I can't type 'a' when the app is open.Lucchesi
yea, i see. add this code after TransformProcessType... it works ;) // switch to Dock.app [[NSWorkspace sharedWorkspace] launchAppWithBundleIdentifier:@"com.apple.dock" options:NSWorkspaceLaunchDefault additionalEventParamDescriptor:nil launchIdentifier:nil]; // switch back [[NSApplication sharedApplication] activateIgnoringOtherApps:TRUE];Curitiba
Thanks, I just added that in but it doesn't seem to change anything, Do you know why?Lucchesi
Hmmm, i've just checked it - it works. New version of joshua_1.1.zip there pupsor.com/wp-content/uploads/2009/07/joshua_1.1.zip check this and make answer. does it work for you?Curitiba
Just checked it and it still doesn't work, I know why because on the second sample project you sent me it wasn't set as LSUIElement. When it is in mine and the first project you sent me.Lucchesi
Make sure at your end on the new test app you sent it is set as LSUIElement, if it is when the App is launched there will be no dock icon, the show button should work and you won't see the apps name in the Menubar. If it is not LSUIElement everything will work like a normal app and the Show button will do nothing.Lucchesi
O
4

(Posting this as an answer because comments don't have code formatting)

QSBApplicationDelegate.m:223-228

BOOL iconInDock = [[NSUserDefaults standardUserDefaults] boolForKey:kQSBIconInDockKey];
if (iconInDock) {
  ProcessSerialNumber psn = { 0, kCurrentProcess };
  TransformProcessType(&psn, kProcessTransformToForegroundApplication);
}
Oddfellow answered 4/7, 2009 at 21:5 Comment(13)
So If I put that code in my App Delegate and connect a checkbox to a User Defaults Controller. Will it work?Lucchesi
Thanks For The Help, Just tried putting the code in but i got quite a few errors. Here is a picture snapplr.com/jckq .Lucchesi
You need to include the right headers (look at the docs for TransformProcessType), use your own preferences rather than a constant from the QSB project, and make your app an LSUIElement in its plist.Pithy
How would I make the app an LSUIElement in the plist?Lucchesi
Add an entry into your Info.plist file where the key is "LSUIElement" and the value is a boolean checkbox that's been checked. Xcode will give you an autocomplete popup with english descriptions of the key. "LSUIElement" corresponds to "Application is agent (UIElement)"Oddfellow
I've done that but i still get these errors (snapplr.com/nqec). What code do I need to add to make it work? Also, does the code in your answer need to be in an action, so i can connect the action to the checkbox?Lucchesi
@Lucchesi "kQSBIconInDock" is a constant defined by the QSB project, and you still haven't imported the headers that define TransformProcessType. In short, you didn't read @smorgan's comment. =)Oddfellow
Oh sorry, I didn't see that comment. I looked at the Docs but I am unsure what i Should put. Is it something like '#import Processes.h' ?Lucchesi
How would I import the Headers?Lucchesi
How would I import the Headers?Lucchesi
@Lucchesi look in the docs for TransformProcessType. Notice that at the top of the documentation, it says "Framework: <Carbon/Carbon.h>". This means you need to link the Carbon framework into your app and then #import <Carbon/Carbon.h>Oddfellow
Just put that line of code in but it doesn't seem to change anything. Here's a picture of it snapplr.com/zgmf.Lucchesi
How How come I still get these errors even though I have imported the correct frameworks?Lucchesi
P
2

You would want to set up your application as LSUIElement, and then use TransformProcessType to enable the Dock icon. The app will need to be relaunched for the change to take effect. See the Google Quick Search Box project for an example.

Pithy answered 4/7, 2009 at 15:42 Comment(2)
Ah I See Thanks, Do you think you would be able to add some code to your answer because I had a look at the google project but there were so many files I couldn't see what they actually hd done.Lucchesi
QSBApplicationDelegate.m lines 223 - 228. They've got the preference itself hooked up to a NSShardDefaultsController. They turn the app into a Dock app on the lines I mentioned.Oddfellow
R
0

Setup your application as an LSUIElement and then call:

[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];

on launch.

This works for the MAS too.

Rowel answered 10/1, 2014 at 21:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.