How to hide EGL surface contents when the native window is unmapped under Wayland? - gtk

We do something like this (simplified) in our code:
auto surface = gdk_wayland_window_get_wl_surface(window);
auto wlSurface = wl_compositor_create_surface(m_wlCompositor);
auto wlEGLWindow = wl_egl_window_create(wlSurface, width, height);
auto eglSurface = eglCreatePlatformWindowSurface(eglDisplay, eglConfig, wlEGLWindow, nullptr);
and then use this surface as usual, e.g. call eglSwapBuffers() on it.
This works fine, but when the window (identified by GdkWindow* window in the code above) is hidden, e.g. because the user switches to another page of the GtkNotebook containing it, the surface remains displayed.
What is the correct way to hide it when the window is hidden and show it back when it becomes visible again?
I've tried resizing the window to 0*0 size in "unmap" GTK callback, but this doesn't seem to have any effect.

Related

enable context menu for specific cell or item in uitable or uilistbox in matlab

I created a uitable (new version using appdesigner) in MATLAB and wanted to support right clicking on cells and showing a cell specific context menu. Much to my surprise there seemed to be no way to support this.
The context menu only seems to trigger with right click on the uitable, but there is no way of knowing which cell was selected (I think, maybe not?). I created a workaround where I left clicked to select a cell, and during that selection I right clicked using a Java Mouse robot to trigger the context menu. This is super ugly but sort of works. Except, if you need to bring up the menu twice on the same cell. Apparently the cell selected callback only fires once for the cell, until a new cell is selected. I tried literally putting two tables in the same spot and upon selecting one toggling to the other, but the memory of cell selection is table specific, so this only worked for two clicks before both tables had been clicked on the same cell, and toggling visibility back to the first resulted in the cell selection callback not firing (since the cell had not changed) . I tried various approaches to try and deselect the cell (disable/enable, visibility change, data change, etc.), but the cell selection callback never changed.
I even tried having duplicate columns, where the goal was to hide a column, where normally columns 1 and 2 would be visible (column 3 out of view due to size), and then on clicking on column 2, column 2 would hide itself (0 width) and column 3 (an exact duplicate) would move into its place, thus seeming to the user like multi-clicking was supported. Unfortunately I can't set the column width to 0 -- or rather, setting it to 0 doesn't completely hide the column. Instead there seems to be some minimal width to the column and the whole thing looked awful.
I wanted to do something similar with a listbox (right click support), but again I couldn't figure out how to identify where I was right clicking. I eventually settled on left clicking on a listbox and using the mouse robot approach to right click to bring up the context menu. Unlike the uitable, it was fairly easy to clear the selection on the listbox (set listbox.Value = {}). However, I strongly dislike the left click instead of right click approach and I'd rather have multiple columns.
Any suggestions would be much appreciated!!!
So I found an approach that is better than using a robot. I had tried this but was missing a critical portion which I will describe below.
Upon selecting a row in the table, the open command can be used to launch a context menu. My problem was that I didn't know where to launch the menu. I tried CurrentPoint for the figure, but it was 0,0 (or in general not valid)
Here's the current documentation for CurrentPoint:
Current point, returned as a two-element vector. The vector contains
the (x, y) coordinates of the mouse pointer, measured from the
lower-left corner of the figure. The values are in units specified by
the Units property.
The coordinates update when you do any of the following:
Press the mouse button within the figure.
Release the mouse button after pressing it within the figure.
Press the mouse button within the figure, and then release it outside
the figure.
Rotate the scroll wheel within the figure.
Move the mouse within the figure (without pressing any buttons),
provided that the WindowButtonMotionFcn property is not empty.
If the figure has a callback that responds to mouse interactions, and
you trigger that callback faster than the system can execute the code,
the coordinates might not reflect the actual location of the pointer.
Instead, they are the location when the callback began execution.
If you use the CurrentPoint property to plot points, the coordinate
values might contain rounding error.
Here's the critical line again:
"Move the mouse within the figure (without pressing any buttons), provided that the WindowButtonMotionFcn property is not empty."
So when a selection of a cell happens, the CurrentPoint is not valid. However, if we simply define a WindowButtonMotionFcn, then it is!
So the general idea is to have a callback for the table when a cell is selected (SelectionChangedFcn) and to set a dummy callback for WindowButtonMotionFcn
The final point is that a context menu can be launched with the open function if you specify a given location to launch it at. This is different from attaching it to an object and having it automatically launch on right click.
Here's some example code. If you comment out the callback for windows motion then the whole thing doesn't work! Unfortunately it is a left click for targeting the cell but at least it avoids the non-sense I was using with a java robot right click.
classdef wtf < handle
properties
h %struct, this was an appdesigner handle
cm %context menu
end
methods
function obj = wtf()
h = struct;
h.UIFigure = uifigure();
h.UITable = uitable(h.UIFigure);
obj.h = h;
obj.h.UITable.CellSelectionCallback = #obj.tableCall;
%obj.h.UITable.SelectionChangedFcn = #obj.tableCall;
%Some data ...
s = struct;
s.a = (1:4)';
s.b = (5:8)';
obj.h.UITable.Data = struct2table(s);
%Our context menu
cm = uicontextmenu(obj.h.UIFigure);
m = uimenu(cm,'Text','Menu1');
obj.cm = cm;
%WTF ... without this we don't get a valid CurrentPoint
obj.h.UIFigure.WindowButtonMotionFcn = #obj.mouseMove;
end
function tableCall(obj,x,y)
%y - event info
%x - impacted object
cp = get (obj.h.UIFigure, 'CurrentPoint');
open(obj.cm,cp(1),cp(2));
selected_cell = y.Indices;
%selected_cell = y.Selection;
x.Selection = []; %allows reselecting same cell without
%needing to select another cell first
%Now we can run something on the context menu
%that targets the selected cell
end
function mouseMove(obj,x,y)
%we could store a point here
end
end
end

How to prevent gtk frame expansion

I am using Gtkmm 3 in Linux with c++.
I want to draw a frame around my ButtonBox that will NOT expand when a resize my window.
This does not work:
Button b1("Hello"), b2("World);
ButtonBox bb;
bb.pack_start(b1, PACK_SHRINK);
bb.pack_start(b2, PACK_SHRINK);
Frame frame("My frame");
frame.add(bb)
Window wn;
wn.add(frame);
Can anyone tell me what will prevent the frame from expanding when I manually resize the window with my mouse. I want the frame to stay around the buttons, not to frame the entire window!
I just found a way!
frame.property_halign() = ALIGN_START;
frame.property_valign() = ALIGN_START;

Getting Mouse Points using Matlab App Designer

I realize that App designer does not support interactive figure manipulation, but I am wondering if I can open a separate figure window (not a UI window) with my graphic displayed on it so that I can still get the location of my mouse clicks. Currently the code below displays the figure on my GUI, and then opens another blank figure that records my mouse clicks. This is fine, but I need to also display the figure in the new window as well, and am having trouble doing so.
first frame = vid(:,:,:,1);
imshow(firstframe,'Parent',app.UIAxes);
[centers_X centers_Y]=getpts;
What worked for me was setting a callback on the image rather than the axes:
ih = imshow(firstframe,'Parent',app.UIAxes);
ih.ButtonDownFcn = {#im_ButtonDownFcn, app}; %app will be passed to the callback
Then in a separate file in the same folder (or as a private function within the appdesigner... it should work but I haven't tried it):
function im_ButtonDownFcn(im, hit, app)
mouse_pos = flip(hit.IntersectionPoint(1:2)); %gives floats. Round if you want integers e.g. for indexing pixels

Matlab GUI Scrollbar Available

Does anyone know if I can make a horizontal and vertical scroll bar in a MATLAB GUI (not a list box)? Depending on the resolution of a computer it may or may not show all of the figure so I need to be able to scroll (horizontally in my case). How to do that?
This will create a figure with a horizontal scrollbar:
figure
plot(1:3);
b = uicontrol('Parent',gcf,...
'Style','slider',...
'Units','Normalize',...
'Position',[0,0,1,0.05],...
'min',0, 'max',1,...
'Value', 0);
However, if I were you, I would rather make sure the figure fits the screen and allow the user to zoom. Having a graph larger than screensize deprives the user from observing the entire graph at once.
You could
a) let matlab choose default figure size of the figure. Then the user can fullscreen if desired, or b)
screensize = get(groot,'Screensize');
figure('Position',screensize)
I hope this helps.

Zoomable image viewer for GTKmm

I need a simple image viewer widget to display a Pixbuf, with a zoom factor that can be changed using the scroll wheel (integer factors only, nearest neighbor interpolation), zooming in should adjust the scroll position such that the current center or mouse position will be the origin. Clicking and dragging the mouse should move the surface accordingly; basically what eog or evince do.
There was once an external gtk-image-viewer component for GTK2, but I haven't found anything elseā€¦
So I tried implementing my own and this is how far I came:
struct ZoomableImage : public Gtk::Scrollable, public Gtk::DrawingArea {
ZoomableImage() {
auto h = get_hadjustment();
}
};
Which leads to a warning
gtk_scrollable_get_hadjustment: assertion `GTK_IS_SCROLLABLE (scrollable)' failed
I couldn't find any proper documentation about how to inherit interfaces in GTKmm, the headers hide a constructor from doxygen which is supposed to be called with the result of a base class's init() function?! Some examples initialize Glib::ObjectBase(typeid(ZoomableImage)), which only adds more errors.
(My idea was to put my ZoomableImage in a ScrolledWindow which should provide me with H/V-adjustments, these range from 0 to the image's real height/width, in on_draw, I would read the adjustment's value, apply the zoom factor and draw the Pixbuf accordingly. Would this make sense?)