mouseclick script help - xcode

I need to get the mouse to click on a spot on the screen, to be specific a flash object in safari....
Id tried to do this with applescript but it didnt work. Then I found this script on the internet.
// File:
// click.m
//
// Compile with:
// gcc -o click click.m -framework ApplicationServices -framework Foundation
//
// Usage:
// ./click -x pixels -y pixels
// At the given coordinates it will click and release.
#import <Foundation/Foundation.h>
#import <ApplicationServices/ApplicationServices.h>
int main(int argc, char *argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSUserDefaults *args = [NSUserDefaults standardUserDefaults];
// grabs command line arguments -x and -y
//
int x = [args integerForKey:#"x"];
int y = [args integerForKey:#"y"];
// The data structure CGPoint represents a point in a two-dimensional
// coordinate system. Here, X and Y distance from upper left, in pixels.
//
CGPoint pt;
pt.x = x;
pt.y = y;
// This is where the magic happens. See CGRemoteOperation.h for details.
//
// CGPostMouseEvent( CGPoint mouseCursorPosition,
// boolean_t updateMouseCursorPosition,
// CGButtonCount buttonCount,
// boolean_t mouseButtonDown, ... )
//
// So, we feed coordinates to CGPostMouseEvent, put the mouse there,
// then click and release.
//
CGPostMouseEvent( pt, 1, 1, 1 );
CGPostMouseEvent( pt, 1, 1, 0 );
[pool release];
return 0;
}
I have only scripted in applescript so I didnt quite understood it
but when I activate it it clicks on the top left
but here is my question, what should I chance in the script to make it click other places than in the top corner
more info about the script on this website: http://hints.macworld.com/article.php?story=2008051406323031

This is stuff that you learn in most introductory programming courses. A complete answer would be very long, so I just tell you a few cornerstones:
The program that you downloaded is not a script
It's objective-C-sourcecode
You need to learn how to work with the Terminal application (the command line).
You need to learn how to invoke commands on the terminal (e.g. gcc)
You have to understand the meaning of the word compile. In this case it's something the author wanted you to do at the command line.
Second step:
// starts a comment in Objective C
gcc ... is the command that should be executed on the command line to compile the program
./click is what you do to invoke the program (after you compiled it :-) )
gcc -o click click.m -framework ApplicationServices -framework Foundation
means:
gcc: Gnu C Compiler
-o click: The program should be named click
click.m: This should be the name of the source code (the file that you called 'script')
hope this helps...

Related

`NSStatusItem` created from `main()` doesn't show up on system status bar

I'm trying to make a simple macOS Cocoa application using NSStatusItem to create a clickable icon on the system status bar. However, when I launch my application, I get this warning and the icon doesn't show up:
2020-03-03 14:43:11.564 Mocha_bug_example[936:39572] CGSGetActiveMenuBarDrawingStyle((CGSConnectionID)[NSApp contextID], &sCachedMenuBarDrawingStyle) returned error 268435459 on line 46 in NSStatusBarMenuBarDrawingStyle _NSStatusBarGetCachedMenuBarDrawingStyle(void)
Here's a minimal reproducible example for my application:
#import <AppKit/AppKit.h>
NSStatusItem* statusItem;
int main (int argc, char* argv[]) {
statusItem = [NSStatusBar.systemStatusBar statusItemWithLength: -1];
statusItem.button.title = #"foobar";
statusItem.visible = YES;
[NSApplication.sharedApplication run];
return 0;
}
I compiled and ran the example like this:
MacBook-Air-5:Mocha ericreed$ clang -o Mocha_bug_example -framework AppKit -fobjc-arc Mocha_bug_example.m
MacBook-Air-5:Mocha ericreed$ ./Mocha_bug_example
2020-03-03 14:43:11.564 Mocha_bug_example[936:39572] CGSGetActiveMenuBarDrawingStyle((CGSConnectionID)[NSApp contextID], &sCachedMenuBarDrawingStyle) returned error 268435459 on line 46 in NSStatusBarMenuBarDrawingStyle _NSStatusBarGetCachedMenuBarDrawingStyle(void)
[Application hung until I pressed Ctrl+C]
^C
MacBook-Air-5:Mocha ericreed$
Note: disabling automatic reference counting and adding [statusItem release]; after calling run as this similar question suggested made no visible difference.
This is how to add status bar item to command line app mac osx cocoa
Adapting apodidae's answer to Swift. Just put this in the main.swift file:
let app = NSApplication()
let statusItem = NSStatusBar.system.statusItem(withLength: -1)
statusItem.button!.title = "Hello, world!"
app.run()
I don't understand the finer details of the NSReleasePool as apodidae included, but it works for me without that.
#import <Cocoa/Cocoa.h>
int main(){
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSApplication *application = [NSApplication sharedApplication];
NSStatusItem* statusItem;
statusItem = [NSStatusBar.systemStatusBar statusItemWithLength: -1];
statusItem.button.title = #"foobar";
statusItem.visible = YES;
[application run];
[pool drain];
return 0;
}
Save file with the name 'statusBar_SO.m'
Compile from Terminal:
clang statusBar_SO.m -framework Cocoa -o statusBar && ./statusBar
This is not the kind of thing you can do in main().
Except for extrememly unusual situations, you should never modify the main() that comes with the application template, and it must call NSApplicationMain():
int main(int argc, char *argv[])
{
// start the application
return NSApplicationMain(argc, (const char **) argv);
}
The Cocoa framework doesn't get initialized until you call NSApplicationMain() and is generally unusable until then.
This kind of setup should be done in applicationWillFinishLaunching or applicationDidFinishLaunching.
Update
The original poster is not using Xcode and is willing to brave the wilderness alone. ;)
This also implies that their application bundle will not have a main NIB file that would normally create and connect the application delegate object, main menu, and so forth.
There are intrepid individuals who have braved this territory and you can read about it in Creating a Cocoa application without NIB files.

how to get windowid from applescript

I am trying to get window id of of every window.
set r to {}
tell application "System Events"
repeat with t in windows of processes
set sid to id of t
set end of r to {title:title of t, id:sid}
end repeat
end tell
r
The above code returns
error "System Events got an error: Can’t get id of item 1 of every window of every process." number -1728 from id of item 1 of every window of every process
How to get the window id of every window?
I wrote a little Objective-C program for you that gets the window owners, window names and window ids:
////////////////////////////////////////////////////////////////////////////////
// windowlist.m
// Mark Setchell
//
// Get list of windows with their WindowOwnerNames, WindowNames and WindowNumbers
//
// Compile with:
// clang windowlist.m -o windowlist -framework coregraphics -framework cocoa
//
// Run with:
// ./windowlist
//
// You can then run "screencapture" to capture that window:
//
// screencapture -l<windowid> -x someFile.[png|jpg|tif]
////////////////////////////////////////////////////////////////////////////////
#include <Cocoa/Cocoa.h>
#include <CoreGraphics/CGWindow.h>
int main(int argc, char **argv)
{
NSArray *windows = (NSArray *)CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements|kCGWindowListOptionOnScreenOnly,kCGNullWindowID);
for(NSDictionary *window in windows){
int WindowNum = [[window objectForKey:(NSString *)kCGWindowNumber] intValue];
NSString* OwnerName = [window objectForKey:(NSString *)kCGWindowOwnerName];
NSString* WindowName= [window objectForKey:(NSString *)kCGWindowName];
printf("%s:%s:%d\n",[OwnerName UTF8String],[WindowName UTF8String],WindowNum);
}
}
Output
./windowlist
Preview:(null):300
Safari:(null):48
Terminal:(null):231
VirtualBox:(null):212
Mail:(null):150
Dropbox:(null):181
Finder:(null):118
Notification Center:(null):83
Google Drive:(null):73
Copy:(null):68
InkServer:(null):49
iTerm:(null):44
Google Drive::69
Copy::66
Dropbox::63
Creative Cloud::57
Spotlight::41
SystemUIServer::33
SystemUIServer:(null):36
SystemUIServer::31
Window Server:Menubar:3
Dock:Dock:23
iTerm:2. bash:190
iTerm:1. bash:336
This is not possible with this code.
In the processes array of System Events the property id of a window is not required to be available in AppleScript, that's the reason why you get the error.
If an application has an AppleScript dictionary and the windows element is provided then all windows have an id property, but not all applications support AppleScript and the non-document based applications don't provide the windows element by default.

How to find the dpi of a monitor on which a specific window is placed in linux?

I want to change the font size when my application window moves from one monitor to another depending on the underlying dpi of destination monitor.
I played with xrandr, xdpyinfo and xlib. I looked at the source code but I couldn't find a way to associate the monitor on which the window (window id) is placed.
Qt has QDesktopWidget, which provides physicalDpiX/Y but only (so it seems) for the primary monitor.
xrandr.h contains XRROutputInfo which delivers mm_width and mm_height, but how can I make the connection to a window id?
Since this question got some attention, I want so share my research. I haven not found a perfect solution. It looks like it's not possible.
But playing with the following code snip will probably help you. The idea is to calculate the underlying display by comparing the window position. If the position is larger then the first screen's resolution, and must be the 2nd monitor. Pretty straight forward.
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#include <stdio.h>
#include <stdlib.h>
// compile: g++ screen_dimension.cpp -lX11 -lXrandr
int main()
{
int wid = atoi( getenv( "WINDOWID" ) );
printf("window id: %i\n", wid);
Display * dpy = XOpenDisplay(NULL);
int screen = DefaultScreen(dpy);
Window root = DefaultRootWindow(dpy);
XRRScreenResources * res = XRRGetScreenResourcesCurrent(dpy, root);
XRROutputInfo * output_info;
for (int i = 0; i < res->noutput; i++)
{
output_info = XRRGetOutputInfo (dpy, res, res->outputs[i]);
if( output_info->connection ) continue; // No connection no crtcs
printf(" (%lu %lu) mm Name: %s connection: %i ncrtc: %i \n", output_info->mm_width
, output_info->mm_height
, output_info->name
, output_info->connection
, output_info->ncrtc
);
}
printf("crtcs:\n");
for( int j = 0; j < output_info->ncrtc; j++ ) {
XRRCrtcInfo * crtc_info = XRRGetCrtcInfo( dpy, res, res->crtcs[ j ] );
if( not crtc_info->noutput ) continue;
printf("%i w: %5i h: %5i x: %5i y: %i\n", j
, crtc_info->width
, crtc_info->height
, crtc_info->x
, crtc_info->y
);
}
}
There are actually 2 functions to query resources about the screens:
XRRGetScreenResourcesCurrent and XRRGetScreenResources. The first one returns some cached value, while the latter one asks the server which may introduce polling. The description (search for RRGetScreenResources):
https://www.x.org/releases/X11R7.6/doc/randrproto/randrproto.txt
Someone went through the trouble timing it:
https://github.com/glfw/glfw/issues/347
XRRGetScreenResourcesCurrent: Tipically from 20 to 100 us. h
XRRGetScreenResources: Typically from 13600 to 13700 us.
Ok, since there is no further discussion here and I am convinced my little program (see above) works, I declare it now as: Answered!
Compile instructions are
g++ screen_dimension.cpp -lX11 -lXrandr
(also added as comment above)
Why so complicated ?! Just get the info from screen where your window is attached.
double dDisplayDPI_H,dDisplayDPI_V;
dDisplayDPI_H = ((double)DisplayWidth( dpy, scr ))/(((double)DisplayWidthMM( dpy, scr ))/25.4);
dDisplayDPI_V = ((double)DisplayHeight( dpy, scr ))/(((double)DisplayHeightMM( dpy, scr ))/25.4);

OpenCV, Qt, imread, namedWindow, imshow does not work

In the .pro file:
QT += core
QT -= gui
TARGET = latihan_2
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
INCLUDEPATH += E:\OpenCV\OpenCV\opencv\build\include
LIBS += E:\OpenCV\OpenCV\opencv\build\x86\mingw\lib\libopencv_core246.dll.a
LIBS += E:\OpenCV\OpenCV\opencv\build\x86\mingw\lib\libopencv_highgui246.dll.a
LIBS += E:\OpenCV\OpenCV\opencv\build\x86\mingw\lib\libopencv_imgproc246.dll.a
LIBS += E:\OpenCV\OpenCV\opencv\build\x86\mingw\lib\libopencv_features2d246.dll.a
LIBS += E:\OpenCV\OpenCV\opencv\build\x86\mingw\lib\libopencv_calib3d246.dll.a
In main.cpp:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
int main(){
//read image
Mat image = imread("img.jpg", 1);
//create image window named "My image"
namedWindow("My Image", CV_WINDOW_AUTOSIZE);
//show the image on window
imshow("My image", image);
//wait key for 5000ms
waitKey(5000);
return 1;
}
When I hit run, there is no error, but it only shows a black window named qtcreator_process_stub.exe.
Why the "My image" window doesn't come out and shows the img.jpg?
I use Qt creator 2.8.1, based on Qt 5.1.1, and openCV-2.4.6.0.
You could also display a cv::Mat on a Qt window. I demonstrate how to do that on cvImage. The code below is adapted from cvImage::_open():
std::string filename = ...
cv::Mat mat = cv::imread(filename);
// Since OpenCV uses BGR order, we need to convert it to RGB
// NOTE: OpenCV 2.x uses CV_BGR2RGB, OpenCV 3.x uses cv::COLOR_BGR2RGB
cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB)
// image is created according to Mat dimensions
QImage image(mat.size().width, mat.size().height, QImage::Format_RGB888);
// Copy cv::Mat to QImage
memcpy(image.scanLine(0), mat.data, static_cast<size_t>(image.width() * image.height() * mat.channels()));
// Display the QImage in a QLabel
QLabel label;
label.setPixmap(QPixmap::fromImage(image));
label.show();
First guess is that the image is in the wrong path, so first test should be to specify the full path to the image.
Also check the return value of your program (make sure the it doesn't return some crash error code - be consistent and return 0 for success and other values for fail).
And a little bit of coding that tells you where the code fails doesn't hurt, so check image.data or you can also use image.empty():
if(! image.data )
{
std::cout << "No image to display";
//can be any other method to display the error: qDebug, a messagebox...
//you can also
return 1;
}
else
{
//use the image
//if nothing goes wrong:
//return 0;
}
Check Projects->Run Settings ->Run in Terminal checkbox. If it is disabled, enable it.
I faced same problem and I solved it by fixing path environment variable. In my path environment variable I added some opencv folders wrongly, then I deleted them and add only bin folder for opencv DLLs and then the problem was solved.

OS X main.m running a server style program

I writing my first OS X command line program which is a server style program. It's job is to process various information and respond to other events.
I have the following code in my main.m
int main(int argc, const char * argv[]) {
#autoreleasepool {
PIPieman *pieman = [[[PIPieman alloc] init] autorelease];
[pieman start];
NSRunLoop *loop = [NSRunLoop currentRunLoop];
while (!pieman.finished && [loop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
}
return 0;
}
I got this code from various documents and the basic idea is that once pieman.finished is set to YES, that the program then exits.
The problem I have is that the flag is being set by code inside pieman, but the run loop is not being triggered, so the program does not exit. I've been looking for ways to trigger the run loop and there seem to be a variety, but none that feel like a good solution. For example I could reduce the beforeDate: to a few seconds to cause periodic triggering of the run loop.
My preference would be that something triggers the run loop on the change of the finished boolean value.
Any suggestions?
You need to tell the run loop to return from runMode:beforeDate:. The NSRunLoop class doesn't define a message to do that, but NSRunLoop is built on CFRunLoop, and the CFRunLoopStop function does what you need.
#implementation PIPieman
...
- (void)setFinished:(BOOL)finished {
_finished = finished;
CFRunLoopStop(CFRunLoopGetMain());
}

Resources