GTK/GDK How to find out if a window is overlayed by another one? - gtk

I've got a gtk application which features a tray icon, if the user clicks on the icon the visibility of the window is toggled when he's on the same workspace as the window is. When he's on another workspace the window moves to that one.
Now, if the application and user are on the same screen and the app is completely overlayed by another one, I want to raise the window so it's on the top, instead of first hiding it and the on the next tray icon click showing it again.
My code so far:
def inOverlayed(self):
windows = self.window.get_screen().get_toplevel_windows()
win = self.window.get_window()
x, y, w, h, b = win.get_geometry()
for i in windows:
if win != i:
x2, y2, w2, h2, b2 = i.get_geometry()
if x >= x2 and x + w <= x2 + w2:
if y >= y2 and y + h <= y2 + h2:
return True
return False
The biggest problem is seems that there is no way to determine a windows z-level, but without one can't distinguish if the window is just inside another one or if it's acutally overlayed by one.
So my question is, how do I find out a windows z-level(the docs don't say anything about this) or is there a simpler solution for this problem

You can't, since the z-level is completely at the discretion of the window manager. GDK can send hints to the window manager about raising or lowering the window in the stack, but the window manager is free to ignore them.
A good substitute for what you want might be to check gtk.Window.is_active(); if true, hide the window, otherwise call gtk.Window.present() on it. This shows the window, de-iconifies it, and moves it to the current desktop all at once.

Related

AHK Run commands every time a window becomes active

I want the NO Button to be pressed when the below window opens, it opens repeatedly and a few after each other.
My current method is to run a timer loop which image searches for the window and then controlclicks the button when the image is found.
SetTimer(Timer, 500)
Timer(){
if ImageSearch(&OutputVarX, &OutputVarY, X1, Y1, X2, Y2, "Image.png") {
ControlClick("Button3", "Information")
}
}
This however is slow because as i said the window apears severa times in busts so i need something that can click the moment the window opens.

Matlab /Wait bar/ Progress bar/GUI

I'm trying to use the wait bar in a gui for a matlab program that recognises images. In simple words, a bounding box(rectangle) appears when there is a irregularity.
The bounding box doesnt appear when I have the waitbar as normal or modal:
f = waitbar(0,'Please wait...','WindowStyle','normal');
But the bounding box appears when I use the following command
f = waitbar(0,'Please wait...','WindowStyle','docked');
I would want the wait bar to pop and not be docked. Any suggestions?
Recommendations?
Thanks
#ssroy, The bounding box(rectangle) is probably added to the figure of the waitbar instead of the figure where you want it. I would try to recall focus to that figure (or your GUI) when adding the bounding box, and follow it by refocussing on the waitbar afterwards.
In order to refocus on the waitbar , you can use again f = waitbar(0,'Please wait...','WindowStyle','normal'); even if you don't change anything on it

AutoHotKey: How to move the position of the progress bar

I have a working progress bar, and wanted to move it to top left corner of the screen. I used x0 y0 w300 to control the position and size.
But doing so my %progress_bar_percentage% stopped updating. I want to ask, is it possible to have the position and progress bar % working at the same time?
a = %counter%
b = %CaseArrayCount%
progress_bar_percentage := Round(((a/b) * 100), 2)
; Draw the progress bar on the screen
Progress, x0 y0 w300, %progress_bar_percentage%, %progress_bar_percentage%`%, System Processing , Sample APP
Reference: https://autohotkey.com/docs/commands/Progress.htm
The documentation actually says that options can only be used if the progress window does not yet exist.
If the progress window does not exist: A new progress window is
created (replacing any old one), and Param1 is a string of zero or
more options from the list below.
That means you can only set the position in the very beginning when creating the progress bar window:
Progress, x0 y0, 0`%, System Processing , Sample APP
Loop, 100 {
Progress, %A_Index%, %A_Index%`%, System Processing , Sample APP
Sleep, 100
}
If you try to use options within the loop, you'll see the progress window being destroyed and newly created with every iteration and the progress value is ignored. According to the documentation if Param1 is an pure number, its bar's position is changed to that value, so you can't actually do both options and progress value at the same time.
Without hacks, the best thing you could do is probably:
Loop, 10 {
value := A_Index*10
Progress, x%value% y%value%, %A_Index%`%, System Processing , Sample APP
Progress, % value, % value "%", System Processing , Sample APP
Sleep, 1000
}

Simply entering the debugger during execution of MATLAB GUI fixes error that persists during normal execution

I'm using a programmatic GUI in MATLAB which uses multiple figure windows. When I press the button 'Redraw' in Figure A, a new figure appears (Figure B) with some data plotted. I want the focus to immediately switch back to Figure A because there are many hotkeys (WindowKeyPressFcn) that I use in that window to update the plots in Figure B.
There are two problems here:
1) The last line of the callback for the button 'Redraw' does switch focus back to Figure A, BUT only if Figure B exists already. That is, the first time Figure B is created, it remains in focus. If I then use Figure A to update the plots in Figure B, the focus correctly switches back to Figure A. I can't think of why it behaves differently during the first redraw and all subsequent calls.
2) The even bigger issue is that if I set a breakpoint anywhere in the code and then resume execution, the focus switches back to Figure A as I want. So, why does entering the debugger and doing nothing else fix the problem? How can I find the issue if everything works in the debugger?
Thanks in advance!
EDIT: To my great surprise, I was able to reproduce this "Heisenbug" by writing my first ever programmatic GUI. This should be the simplest example of my problem. To see it in action, simply run the code below and click on the push button. For some reason, when Window 2 is created for the first time, the focus does NOT switch back to Window 1 as intended. It works properly for all subsequent button presses. Try closing Window 2 and pushing the button again, the error will keep occurring.
As mentioned in the original post, setting a breakpoint in the code resolves the issue. Set a breakpoint at line 27, then resume execution and Window 1 will be in focus.
What is happening here?
function heisenbug
%% Main problem:
% After clicking the push button, I want the focus to
% always switch back to Window 1 (the one containing the button).
% However, this does not work when Window 2 is first created.
%%
%% Create and then hide the GUI as it is being constructed
f = figure('Visible','off','name','Window 1','units','normalized','Position',[0.1 0.1 0.5 0.5]);
%% Initialize handles structure
handles = guihandles(f);
handles.window2 = [];
guidata(f,handles)
%% Make a button
hbutton = uicontrol('Style','pushbutton','String','Push me','units','normalized',...
'Position',[0.1 0.1 0.8 0.8],...
'Callback',#button_Callback);
%% Make the GUI visible
f.Visible = 'on';
%% Button callback
function button_Callback(source,eventData)
handles = guidata(gcbo);
% If Window 2 already exists, plot a circle, then switch focus back to Window 1.
if ~isempty(handles.window2) && ishandle(handles.window2)
figure(handles.window2);
plot(1,1,'bo')
figure(f);
% Otherwise, create Window 2 and do the same thing.
else
handles.window2 = figure('Name','Window 2','units','normalized','position',[0.4 0.1 0.5 0.5]);
plot(1,1,'bo')
figure(f)
end
guidata(source,handles)
end
end
My post was quickly answered by Adam (thanks!) on the MathWorks site: http://se.mathworks.com/matlabcentral/answers/299607-simply-entering-the-debugger-during-execution-of-matlab-gui-fixes-error-that-persists-during-normal.
I needed to insert a pause(0.05) after Window 2 is created, before trying to switch the focus back with figure(f). Otherwise the focus is stolen back to Window 2 when it finishes plotting.

Trying to determine if mouse clicked inside window region

I have a simple Autohotkey script that I want to use to determine if the mouse was clicked inside a window. I want the function to fail if the click was on the title bar or on the scroll bars of the window. My script looks like this:
LButton::
WinGetPos, X, Y, Width, Height, A
MouseGetPos, x,y
Rightmargin := Width - 50
Topmargin := Y+25
if (x < Rightmargin and y > Topmargin)
MsgBox You're Inside
return
The problem is when I run this, it freezes up my machine. All the left mouse clicks are captured and do not get through to the system and for some reason the test case always fails (I never see the MsgBox).
Can you tell me what I am doing wrong?
Variables, Labelnames and so on are case-insensitive in AutoHotkey. So, with WinGetPos, X, Y and MouseGetPos, x,y, you are allocating these two variables twice, overwriting the window's position coordinates. So, for example, you might want to rename x to mouseX and y to mouseY.
Since you obviously want your mouse coordinates being measured by the current window, you should also include coordmode, mouse, relative before your hotkey assignments.
Finally, if you also want your Click to be send to the window, includ a tilde ~ before your Hotkey: ~LButton::.