Deactivate macro for non-dock application

There are applications where you have the option to hide their dock icon .. Like "ticktick", "current" [ messenger client for mac ] and launchbar.

I have a macro that trigger when typing a key [ "t" or "h" .. ] without a modifier.

The problem is that these macros don't deactivate when one the 3 apps listed above are activated because it considers that the app that is now in the background is in the front, so i can't type these keys.

Is there a way to tell keyboard maestro to stop triggering these macro under these conditions ?

PS : using an "if then" action with one of the 3 applications "is at the front" doesn't work

here is an exemple of a situation that i was talking about

I'm not entirely clear what the problem is, but couldn't you use the Find Image condition to detect whether the logo for the Lauchbar is in the upper left corner of the screen?

If I'm misunderstanding the problem, I apologize.

If the problem is that you are trying to detect if an Application is in the menu bar on the top, then the OCR condition could also work well to solve that.

You wouldn't modify the trigger, you would just put a test at the top of the macro to check what is on the screen before proceeding.

@Sleepy The search bar doesn't have an icon .. i just search in the word "launchbar" so the related icon application appeared.
If I don't have an icon, how can i use the "find image conditon" or there is another way of doing this ?

Have you tried putting these macros in a Macro Group that is NOT Activated when the target apps are frontmost?

image

JM's suggestion is excellent, but if it doesn't work, I'm sure we can still fix it. There are other ways to tell if a program is running. JM's idea was to use one of the features in KM. I have another idea. You can use the Execute Shell Script action and return the result of a test which checks if the Launcher process is running. Try JM's idea, and if that doesn't work, we'll give you other methods.

I have tried JM's suggestion, it doesn't work.

Ok, the first thing is understanding the problem. When you spoke about "activating" the macros I presume you meant either triggering or running them.

If your macro is triggered and starts running, I think it would be satisfactory to you if the macro determined that one of those programs was running and just exited. Right?

JM's solution was attempting to stop those programs from triggering at all. That's what you asked for. And that would be the best solution if it worked. My idea is to let them activate but to exit if one of those programs are running. Do you see the difference?

image

The first problem is that the KM action will "eat" the key if it triggers. But we can solve that later, I just want to know if this solution otherwise works before I solve the key-eating problem.

Also the correct way to do this is to include the full path of the name of the program, but you didn't indicate the full path of your apps, so I just put "ticktock" in this example. You will have to determine the correct path of the files you want to check for. To do that open a terminal window and enter the command "ps -ax" and then copy the correct strings from that output into your KM action.

If my method works, then we can modify it to make it more efficient. People may attack my method saying I'm running three tests instead of a single test, but that can be tweaked later. The main issue for the moment is does it work?

We could be making incorrect assumptions about your situation. It might help us if you showed us your actual trigger rather than just describing the trigger.

Let me reiterate that my solution absolutely is not the best way to solve this. My solution is inefficient and requires extra code and extra triggers. I am not offended if you refuse to implement my solution for these reasons. But if you are having trouble with JM's trigger solution, then this could be worth trying to see if it works.

2 Likes

@Imed, can you please be more specific? Exactly what "doesn't work"?

Please post a screenshot of your Macro Group setup.

@JMichaelTX @Sleepy here is my macro
one key trigger macro.kmmacros (4.2 KB)

I want to cancel this macro when one of the 3 apps are used. Or in another way, i want to trigger this macro only when i'm not using these 3 apps (and "pdf expert" is at the front of course !).

Knowing that i use these 3 apps for typing, when I type "te" I only get "e". So the macro doesn't work.
Here is the screenshot for each app when pdf expert is in the background.

LAUNCHBAR :

TICKTICK :

CURRENT :

If it's helpful for you, I use a keyboard shortcut for opening each of these 3 apps :

  • launchbar : ⌥ + space
  • ticktick : ⌘ + ⌥ + space
  • current : ⌘ + ⌥ + z

@Sleepy I have tried your method, I still get the same result ("e" instead of "te").
Sleepy method.kmmacros (4.1 KB)

You were close the solution when you guessed at putting the Type T command inside the macro. But you put it in the wrong place. This is the "second problem" I spoke about earlier which I told you I would address once the first problem was solved. You are trying to solve both problems at once and I was trying to solve one problem at a time. I'm not finished solving the first problem yet, but since you are eager to solve everything at once I'll help you with that. The only thing I ask is if we have to step back a bit, don't get upset with me.

The macro in this case always eats the key. So we need to always un-eat the key because we never want a key to disappear. The purpose of the "IF statement" that I gave you was to "CANCEL THE MACRO" if one of the apps worked. Assuming that my code worked, and I'm fairly sure it did, the "Type T" command must be moved to before the "IF statement" and the code that you want to run ONLY if one of the three apps isn't running needs to be placed after the "IF statement."

Let me reiterate one more time, I know you want to " trigger this macro only when i'm not using these 3 apps". As I said, that's the solution JM was trying to give you, and I was building you the opposite solution. I was building a solution that still triggers whether those applications were running, but cancels itself if it detects one of those programs. And I think my solution will have the same result. As I said before, JM's approach would be better, but if it didn't work for you, for reasons we can't figure out, then my approach should work.

So even if my solution works 100%, we probably should try to figure out why JM's solution doesn't work for you. Because his approach is simpler.

2 Likes

Sorry, I overlooked the obvious when I first read and responded to your request.
Unfortunately, I don't think there is any way to do what you want, because, as you state, KM can NOT detect when apps like LaunchBar are frontmost. KM simply does NOT see these type of windows.

So you are currently using "t" as the trigger for the macro you want to use with PDF Expert.
My suggestion is to use some modifier key with the "t". For cases like these often use OPTION modifier. So you would type "⌥t" instead of "t".

I even tried using a Palette when PDF Expert is frontmost, but the "t" is still captured by KM when LB is frontmost.

1 Like

I tried to do what you asked and it worked. The macro triggers normally when I'm using "pdf expert" and when I type in the 3 app the "t" letter appear normally BUT, the screen flashes white every time i trigger the macro as if there is an error .. do you know why this is hapenning ?

Sleepy method v.2.kmmacros (4.5 KB)

I'm happy for you and for me, as my advice is occasionally wrong (~20% of the time.) This solution may work, but it would technically be better if we could figure out how to actually stop it from triggering when it shouldn't. This is why JM's approach is probably better than mine, if we can get that to work. But if you are satisfied with this approach, then that's okay too.

There might be a few things we can do to clean up this method.

Ooh. I don't think the flashing is coming from KM since I use this all the time and I never see any flashing. My guess is that it's coming from one of your apps. If you are willing to upload a video of it I'd be happy to look at it and make a guess. You didn't indicate if the flashing only occurs with PDF Expert or if it happens with LaunchBar and the other apps you use.

Flashing is undesirable. And if you say it's unacceptable, we'll try to diagnose it.

Oh I think (10% chance) I may see why your screen is flashing. That's because I said you should MOVE the Type T command to the top and you COPIED it instead. You're supposed to MOVE it which means delete it from the occurrence at the end of your macro.

And here's one way you can clean up the messy logic in the current macro. Try this approach for cleaner code: (sorry about the typo 5 minutes ago, this version should work)

image

image

This will remove the three conditions and replace it with a single condition. Overall it looks cleaner. You will need to replace "..." with the full path name.

I'm sorry for not replying these days [ I had exams ]

I now think that your macro doesn't work BECAUSE it is based on "if the programs are running" then cancel the macro .. But the problem is these 3 apps are always running in the background, when I trigger their respective keyboard shortcut, I'm not launching them, I'm just bringing them to the front.

I thought it worked before but I figured that I had the letter "t" appear when i typed only because I put the "type keystroke action" to simulate the letter "t" and after that the "command+alt+T" which causes of the screen to flash white when I'm not in pdf expert.

I hope i'm wrong and there is a real solution to this.. thank you again !

No worries about the exams. I've been there too, a long time ago.

I think I understand your latest message. I originally had thought you wanted the macro to be cancelled or not activated "if those programs were running". I thought that's what you meant. But now you say that they are "always running". So what you seem to want is for the macro to not activate if they are visible on the screen. That's easy too. As I said in an earlier post there are "other methods."

You can just use my last approach but instead of testing via the results of the ps command you test via the results of the Find Image macro. I notice that when the launchBar is activated there's a big letter B near the upper left corner of the screen. So just cancel the macro if it finds that image in the upper left corner of the screen.

I still think JM's approach is the cleanest and most reliable approach. but you said it "didn't work". Perhaps it didn't, but you didn't show us the "macro group" for that attempt. JM asked you for a screenshot of your macro group setup, but you didn't show that, all you showed was the macro itself, not the macro group. So I have a sneaking suspicion that you didn't follow JM's instructions correctly. Can you please "post the screenshot of your macro group setup"? I hope you aren't upset with me for asking, but since you didn't post that, I'm suspecting you didn't know where to look for that.

Maybe you did do all the right things, but until we see the screenshot, we can't be 100% sure. If I'm wrong, I apologize, but there's a small chance that I'm right.

Okay, thank you for the other method. I'll try changing it to the "find image macro".
For the macro, it's just the "global macro group" i tried with the default settings and with JM's suggestion [ except for these 2 apps ].

I think @Sleepy has the right approach, but just needed a way to be able access more granular information about what windows are visible on the screen at any one time. So if this works, credit remains his. If it doesn't work, it'll just be one of those application processes annoyingly having a slightly different name to the application itself, which shouldn't happen (but sometimes does, as Alfred did for a long time, and now thankfully has had that corrected), but it'll be a simple fix.

image

JavaScript for Automation (JXA) Script
ObjC.import('CoreGraphics');	
unwrap = ObjC.deepUnwrap.bind(ObjC);

(() => {	
	const w_info   = unwrap($.CGWindowListCopyWindowInfo(17, 3)),
	      z_item_0 = w_info.find(x => x.kCGWindowOwnerName=='SystemUIServer'
	                               && x.kCGWindowName=='NotificationCenter')
			               .kCGWindowLayer;
	return [...new Set(w_info
	           .filter(x => x.kCGWindowLayer!==z_item_0
		                 && x.kCGWindowLayer!==z_item_0-1)
	              .map(x => x.kCGWindowOwnerName) )];
})();
Regular Expression
(?i)(TickTick|LaunchBar|Current)(,|$)
2 Likes