I want to make a text replacement program for linux. ie I type something like .alog, and it gets replaced with /usr/local/apache/logs/. I know I can do this with alaises, but I am often remotely logged on machines that do not have such alaises.
I am also interested in doing this for learning purposes.
I see some info online about grab and send keystrokes in X for a window I make, but can't find info on doing it for all windows in the workspace.
Any suggestions on how to do this would be greatly appreciated.
You may wish to start with the code of a window manager as a starting point; Window Managers bind keys to work regardless of window, this is probably a good start. dwm is widely held to have beautiful code.
setup() appears to add its event mask to the root window directly:
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
/* ... */
/* select for events */
wa.cursor = cursor[CurNormal];
wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask|ButtonPressMask|PointerMotionMask
|EnterWindowMask|LeaveWindowMask|StructureNotifyMask|PropertyChangeMask;
XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa);
XSelectInput(dpy, root, wa.event_mask);
grabkeys();
Related
I'm making a hobby project that is basically a bot for a very old flash game, the mouse move and click works fine, but all key presses make the operating system lag/stutter and sometimes stop listening to all keyboard inputs, real or fake.
I started using just XLib with XTests but didn't work, so I tried XSendEvent instead of XTests, but all symptoms stayed the same, so the last attempt was with XDO, which gave better results, but still freezes the OS.
this is the current snippet that I'm trying to use to simulate a keypress:
//Constructor
CheatCore::CheatCore() {
xdo_t x = xdo_new(NULL);
Window *list;
xdo_search_t search;
unsigned int nwindows;
memset(&search, 0, sizeof(xdo_search_t));
search.max_depth = -1;
search.require = xdo_search::SEARCH_ANY;
search.searchmask = SEARCH_CLASS | SEARCH_ONLYVISIBLE;
search.winclass = "Chrome";
int id = xdo_search_windows(x, &search, &list, &nwindows);
qDebug() << nwindows;
if(!nwindows){
qDebug() << "Chrome not found";
return;
}
w = list[0];
//I have to call activate twice to really bring it forward, I suspect that its
//because I use a transparent "overlay" that show stats for the cheat and it is set as Aways on top
//(i used Qt to set it to not get any Events)
xdo_activate_window(x,w);
xdo_activate_window(x,w);
}
//there is a function that executes every second to check if a pixel color has changed,
//if so, then the SendKey is called to Reload weapon magazine pressing the "space" key
void CheatCore::SendKey(){
xdo_activate_window(x,w);
xdo_activate_window(x,w);
xdo_send_keysequence_window(x, w, "space", 500);
}
I'm using a transparent overlay to show the bot status, with just some numbers appearing, it is a widget created using Qt that is AlwaysOnTop and the paint event draws the desired information's, it is another object and don't have direct impact in the CheatCore, but this is the window flags used to draw over a transparent window and ignore events.
setWindowFlags(Qt::WindowTransparentForInput | Qt::FramelessWindowHint |
Qt::WindowStaysOnTopHint);
setAttribute(Qt::WA_NoSystemBackground);
setAttribute(Qt::WA_TranslucentBackground);
setAttribute(Qt::WA_TransparentForMouseEvents);
I didn't manage to understand what could be provoking this weird behavior, could it be the windowing system?
Also, I tried to find a Qt way of simulating mouse/keyboard inputs, but i didn't manage to find any solution to send events to other windows if there is a way possible of achieving this would be great!
The game i'm trying to automate is called "Storm the House"
If interested this is the link to the online repo : link
Can you help me make this work? Thank you!
Context about the setup:
Ubuntu 18.10 using VGA and Nvidia drivers (if it may influence the xserver)
Did you ever try to use xdotool from command line. To use xdotool you need to install package first.
To simualte a key press, you can use.
xdotool key <key>
For example if you want to simulate key press for X you can use this code
xdotool key x
Or any other combination like
xdotool key ctrl+f
Also you can replace key press with another one, for example if you want to replace pressing D with Backspace you can try this one
xdotool key D BackSpace
You can read complete guid online, also you can write script with this tool and use it in many different situations.
Also you can use it for remote connection too.
I hope this helps you with your little problem.
Using evdev is a linux specific option.
It's a simpler solution as you just need to open the correct file and write to it.
Take a look at this similar question to see how to get started.
I am trying to create a simple panel for Openbox in Arch Linux using c++, but I cannot figure out how to remove the title bar from a window.
I am creating the window with XCreateWindow(...), and that gives a window with the correct size, but it contains a title bar, and the window also opens in the top-left corner of the screen, no matter what offset coordinates I specify.
I read here that both of these problems are probably caused by the window manager (Openbox), which overrides the window attributes I specified in XCreateWindow(..., &window_attributes). This could be solved by adding window_attributes.override_redirect = True;, although this does not seem to do anything for me. When I try this I get the exact same window as before. (I did compile the file after this change.)
Also I read into the code of Tint2 (link), which is another panel for Openbox. They create a window using the following code:
XSetWindowAttributes att = { .colormap=server.colormap, .background_pixel=0, .border_pixel=0 };
p->main_win = XCreateWindow(server.dsp, server.root_win, p->posx, p->posy, p->area.width, p->area.height, 0, server.depth, InputOutput, server.visual, mask, &att);
I don't see an override_redirect anywhere in their code, so I'm not sure how they are removing the title bar.
As additional information, I thought it would be worth mentioning how I'm executing the script:
/* The c++ file is saved as 'panel.cpp' */
$ gcc panel.cpp -lX11 -o panel
$ ./panel
Also, I am running Arch Linux through VirtualBox with Windows 8 as host. I'm not sure if this changes anything, but it won't hurt to mention.
Since I found the solution, I figured I'd post the solution here if anyone else needs it.
As #JoachimPileborg mentioned, I needed to alter the Openbox settings in ~/.config/openbox/rc.xml. Inside the <applications> tag, I added the following code:
<application class="*">
<decor>no</decor>
<position force="no"></position>
</application>
The class="*" means that all applications will follow these rules, you could fill in the class name of the application instead. The <decor>no</decor> removes the title bar, and <position force="no"></position> ensures that my own script is able to handle the positioning. You could also add another <application> tag after this one to make exceptions to this rule.
Also, the window_attributes.override_redirect = True; is not needed anymore.
A more correct way is to use the Extended Window Manager Hints.
The idea is that you don't tell the window manager how to decorate or not your window, you just indicate the window type with _NET_WM_WINDOW_TYPE :
Atom window_type = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
long value = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DOCK", False);
XChangeProperty(display, your_window, window_type,
XA_ATOM, 32, PropModeReplace, (unsigned char *) &value,1 );
"Dock" is the type for panels and taskbar. Usually they are undecorated and appear on all desktops. As written on the documentation, previously the _MOTIF_WM_HINTS property was used to define the appearance and decorations of the window. Window managers still support it, but _NET_WM_WINDOW_TYPE is prefered as it describe the function and let the window manager (and user) decide on the appearance and behavior of that type of window.
Another interesting property for a panel is _NET_WM_STRUT_PARTIAL, to "reserve" space.
So, (I rewrote this since a lot of people didn't understand me. I apologize.)
I'd like to bring the window of my qt application to the very front of ALL windows on screen.
I've heard you can do this by attaching to the thread of the foreground window and then "stealing focus" aka putting yourself where that foreground window was.
(I'm using OSX, so windows.h is no option for me.)
I hope you understand now.
To bring a window to the front, ensure the window is visible, then activate the window.
As the docs state: -
Sets the top-level widget containing this widget to be the active window.
And
If you want to ensure that the window is stacked on top as well you should also call raise().
So, assuming you have a window called pWindow, you can do something like this: -
pWindow->raise();
pWindow->show();
pWindow->activateWindow();
Also note that OS X can have multiple desktops (Spaces). If you also want the window to track the user's Space when they switch between them, you can add this function to your window class: -
void MyWindow::DisplayOnAllSpaces()
{
// ensure we stay on the active desktop
WId windowObject = this->winId();
objc_object* nsviewObject = reinterpret_cast<objc_object *>(windowObject);
objc_object* nsWindowObject = objc_msgSend(nsviewObject, sel_registerName("window"));
int NSWindowCollectionBehaviorCanJoinAllSpaces = 1 << 0;
objc_msgSend(nsWindowObject, sel_registerName("setCollectionBehavior:"), NSWindowCollectionBehaviorCanJoinAllSpaces);
}
I'm writing my own class to create and handle a progress/overlayicons for a programs taskbar icon.
I'm using the ITaskbarList3 for Windows 7/higher to do this. I can now create a progress or overlayicons, but what I'm missing is the alert/blink effect, that appears if a program wants to get the users attention (e.g. if you have to confirm admin rights and are working on a different tab).
I do not mean the pause/error-indicators for a progress, I need the blinking orange effect, and i wasn't able to find something until now.
Thanks for your help.
Use FlashWindowEx function. See the doc on FLASHWINFO - you can start flashing, stop flashing and specify flashing parameters.
For continuous blinking until the user clicks on the window the code is like this:
FLASHWINFO fi;
fi.cbSize = sizeof(FLASHWINFO);
fi.hwnd = yourHwnd;
fi.dwFlags = FLASHW_ALL | FLASHW_TIMERNOFG;
fi.uCount = 0;
fi.dwTimeout = 0;
FlashWindowEx(&fi);
I need to write a C++ GUI such that user can make a flowchart / pipeline by selecting several blocks from a toolbar and putting them into a window and connecting them in some order which he wants and then program runs the flowchart. (For simplicity just consider each block's task is to print some number. My problem is GUI)
Does anyone ever try a similar thing / any experience?
Is it possible to make such a GUI in WxWidget or any other Graphics/Window-form library?
Is it possible to use VTK to make the GUI?
Do you know of any similar open source work?
I have developed several apps with GUIs that do this sort of thing.
The one I am most pleased with is called VASE: A GUI used to create the layout, set parameters and view results of a process flow simulator.
It is not a trivial task, though once you have done one or two, there are many ideas that you can reuse and it goes quickly.
The two biggest challenges drawing the lines connecting the objects ( as you can see, even in VASE, this problem is not completely solved ) and storing that layout in a format that can be easily recovered and redrawn.
Is there any particular issue you need help with?
If you want a really, really, simple example to get you started I have re-implemented a couple of basic features ( all nice and clean, no copyright restrictions ) - left click to select, drag to move, right click to connect.
Here is the source code repository - http://66.199.140.183/cgi-bin/vase.cgi/home
Here's what it looks like
I have implemented a simplified connector, which I call a pipe. To give you a flavour of how to do this kind of stuff, here is the code to add a pipe when the user right clicks
/**
User has right clicked
If he right clicks on a flower
and there is a different flower selected
then connect the selected flower to the right clicked flower
if he right clicks on empty background
create a new flower
*/
void cVase::MouseRightDown( wxMouseEvent& event )
{
// find flower under click
iterator iter_flower_clicked = find( event.GetPosition() );
// check there was a flower under click
if( iter_flower_clicked != end() ) {
// check that we have a selected flower
if( ! mySelected )
return;
// check that selected flower is different from one clicked
if( mySelected == (*iter_flower_clicked) )
return;
// construct pipe from selected flower to clicked flower
myPipe.push_back(cPipe( mySelected, *iter_flower_clicked ));
} else {
// no flower under click
// make one appear!
cFlower * pflower = Add();
pflower->setLocation( event.GetPosition() );
}
// redraw everything
Refresh();
}
And here is the code to draw a pipe
/**
Draw the pipe
From starting flower's exit port to ending flower's entry port
*/
void cPipe::Paint( wxPaintDC& dc )
{
dc.SetPen( *wxBLUE_PEN );
dc.DrawLine( myStart->getExitPort(), myEnd->getEntryPort() );
}
You can see the rest of the wxWidgets code that ties all this together by browsing the source code repository.
I think using a library such as wxArt2D would be easier than using the standard wxWidgets drawing classes. The wires sample of wxArt2D looks similar to what you are looking for.
Maybe you can have a try with the tiny tool called Flowchart to Code, you can get the flowchart needed,like this. It can be downloaded here:http://www.athtek.com/flowchart-to-code.html#.Ug4z29JPTfI