GTK: positioning context menu items w.r.t context menu - c

I am working on a defect in my GTK code for displaying context menus. After creating a menu with a number of menu items, I use gtk_menu_popup() to display the menu. This function takes a function pointer of type GtkMenuPositionFunc which lets me position the menu. I don't really do anything here except tell GTK to keep current position but push the menu in if part of the menu is outside the monitor (using the fourth argument to the function). My problem is that when GTK pushes the menu in, the absolute position of the menu items does not change. Hence their scroll position changes resulting in scroll bars in the menu. I want the relative position of the menu items w.r.t the menu to remain fixed. Is there any way I can do that? The GTK documentation does warn about this problem, but does not say anything about how to fix it. There is the link to it for reference:
http://library.gnome.org/devel/gtk/unstable/GtkMenu.html#GtkMenuPositionFunc
EDIT: I would have liked to include some code, but the logic is too scattered for that.

You don't need to provide a positioning function if you just want the default behavior. The default behavior is to keep the current position but make sure the menu fits on the monitor, so you can just pass NULL as the positioning function.
You can also take a look at how the default positioning function is written: http://git.gnome.org/browse/gtk+/tree/gtk/gtkmenu.c, gtk_menu_position() currently at line 4288.
PS. If your logic is too scattered to post a code sample, then you should consider cleaning it up.

I was not able to find any way to readjust the scroll-offset of menu items once the menu is pushed in. So, the workaround I used was to avoid having GTK push the menu in vertically. Hence, the original request was to create the menu at position (x,y) but resulted in length L of the menu going out of the screen, I reposition the menu at (x,y-L) in my position function. Similarly, if y<0 I change set it to (x,0). I still tell GTK to push in any menu that goes outside the screen to take care of menus going over the left and right margins.

Related

React material ui: how to disable pointer capture when touching and dragging outside a Card?

I'm using React, and have a material UI Card that toggles on and off when clicked. I am trying to 1) get the card to toggle on/off correctly if the user long-presses it, and 2) disable the card toggling if the user presses it and slides(drags) away, then releases. Performing these actions with a mouse has all the desired effects, and there are no problems. However, my app is used on a touch-screen monitor (without a mouse) and so I must replicate the same outcomes with touching the screen.
Initially, I was using the onClick event handler to toggle the card. Long pressing with your finger (the first issue) was not properly toggling it. After a bit of research, I learned that mouse and touch events were combined into one: pointer events. So I switched onClick to onPointerUp and it worked magically.
However, this is where the second issue comes in. If the user clicks the card and drags his or her finger away from it and releases, it still gets toggled (using the mouse doesn't have this same effect). I did some digging and according to MDN, pointer capture could be related:
Pointer capture allows events for a particular pointer event (PointerEvent) to be re-targeted to a particular element instead of the normal (or hit test) target at a pointer's location. This can be used to ensure that an element continues to receive pointer events even if the pointer device's contact moves off the element (such as by scrolling or panning).
My question is, why is the mouse click working correctly while touching doesn't? And how does one go about disabling the card getting toggled when your finger is dragged away from it?
Codesandbox of sample
Edit: Forgot to mention, I want the card to toggle correctly as long as the touch is released while on the card (even if it is dragged away and returns). This works fine with the mouse, but for touching, it toggles regardless of where your finger is released.
Edit2: Added codesandbox link.
Some things of note: touch-action is set to none (CSS) and this is where the strange behavior happens, but I need to have it set that way to prevent unwanted touch registers like scrolling.
I also noticed that for mouse clicks, you can select a card by clicking outside the card and dragging into it and releasing the click. I guess since the event is onPointerUp that would make sense. Although this effect is undesirable, users will only use touching in my app so it's not something I have to worry about. Regardless, I would like to understand the right way to approach this and how to achieve my desired effects.

Only want element to render when user scrolls to that section

I have this animated graph on my website that you have to scroll a bit down to get to. The animation always happens immediately meaning that no one can see it actually being made since they haven't scrolled down yet. I was wondering if there is any way to make it so that that element only appears when the user scrolls to that portion of the screen?
npm i react-bottom-scroll-listener
please refer https://github.com/karl-run/react-bottom-scroll-listener#readme this gives you a listener where you can set a condition and enable it

Can't properly force a component on-screen with scrollComponentToVisible

On a given form, we replace one component with another.
The original component is a series of TextFields, and the new form is some informational text and a button. We hide the first one, and show the second one (the UI designer has both Containers within the form).
I tried using scrollRectToVisible with various values but it didn't seem to make any difference with the scrolling.
continueButtonContainer.setHidden(false);
f.forceRevalidate();
Button continueButton =
(Button)StateMachine.GetInstance().findByName("ButtonContinue", f);
f.scrollComponentToVisible(continueButtonContainer);
f.scrollComponentToVisible(continueButton);
I'm expecting the continue button to be near the top of the screen.
If the screen was scrolled before displaying the continue button, the button ends up right at the bottom of the screen (it was below the bottom of the screen before I put in the scrollComponentToVisible line(s).
After the user scrolls the screen, the button goes up to where it needs to be, and stays there.
If the screen is not scrolled, the button appears where it should be.
I know I can probably add some invisible containers underneath the button and force them onto the screen, but I would rather have a slightly more robust solution.
There are a few issues with this. First you are using forceRevalidate which should be used in very rare cases.
Second it seems that you are invoking this on a Form, this is a bit misleading. While it seems that:
f.add(myCmp);
Adds a component to the form it is really a synonym to:
f.getContentPane().add(myCmp);
That's important because you need to invoke the scrollComponentToVisible on the scrollable container which will actually do the work and ideally be the direct parent of said component. I'm assuming it's the content pane in your case but it depends on layout etc.
The last part is letting the layout do its job. If you are invoking this before the form is showing this might not work. Notice that doing it after a call to show is meaningless as the form might take time with transitions. You can use a show listener or override the laidOut callback method to perform things like this.

Difference between KeyboardNavigationMode Contained and Cycle?

Short question - what is the real difference put in easy and understandable words?..
Extracts from MSDN:
Contained - Depending on the direction of the navigation, focus returns to the first or the last item when the end or the beginning of the container is reached, but does not move past the beginning or end of the container.
Cycle - Depending on the direction of the navigation, the focus returns to the first or the last item when the end or the beginning of the container is reached. Focus cannot leave the container using logical navigation.
The difference is in the last part of the description of those modes. But I cannot understand it. Can anyone explain it in a more humane way?
The KeyboardNavigation class defines three attached properties that allow the modification of each of the navigation modes:
KeyboardNavigation.TabNavigation,
KeyboardNavigation.DirectionalNavigation,
KeyboardNavigation.ControlTabNavigation
Each of these properties defines six possible values.These values specifies how the navigation can be done in a list control(eg:ListBox,listview)
for instance;
KeyboardNavigation.DirectionalNavigation="Contained"
is used to indicate that when i press the down or up arrow in the keyboard to navigate between items in a list,the navigation stops at the last item or first item,then we have to use the opposite button to navigate further up or down.
KeyboardNavigation.DirectionalNavigation="Cycle"
is used to indicate that when i press the down or up arrow in the keyboard to navigate between items in a list,the navigation continues from the top or bottom item in a cyclic manner
same is the case with TabNavigation which indicate the navigation mode when we press the tab button in a list

Show NotifyIcon Context Menu and Control Its Position?

I'm trying to show a context menu when I left-click a NotifyIcon. Just calling NotifyIcon.ContextMenuStrip.Show() doesn't work very well. A solution has been posted here before that calls a secret method using Reflection:
Dim mi As System.Reflection.MethodInfo = GetType(NotifyIcon).GetMethod("ShowContextMenu", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic)
mi.Invoke(Icon, Nothing)
This works great, except that I also need to control where the menu is shown. I want to wait for the SystemInformation.DoubleClickTime to elapse between receiving the NotifyIcon.MouseUp event and displaying the menu, so that I can handle single-clicks and double-clicks separately. But invoking the ShowContextMenu method displays the menu at the current mouse position when ShowContextMenu is called, not when the icon was actually clicked. Which means that if the mouse moved during the DoubleClickTime, the menu will be displayed in a different part of the screen. So if I can control where the menu is shown, I can just save the mouse coordinates when I receive the MouseUp event, and then I can ensure that the menu is displayed near the icon. Is there a way to do this?
Thanks in advance.
Well, I just discovered that there are existing programs that exhibit this same behavior. I just went through all the icons in my system tray and about half of them do it. If you left-click the icon and then move the mouse during the delay before the menu appears, the menu will appear at the last mouse location, wherever that is on the screen. Snagit is one application that does this. Outlook is the only program in my tray that always shows the menu where I clicked the icon. But Snagit looks like it's using a .NET ContextMenuStrip, while Outlook is probably using a native menu.
So either this is standard behavior, or it's a problem that no one else has been able to solve either. And as a user, I've never noticed this behavior until yesterday when I was testing my own application. So I guess it's not that big of a deal and I won't worry about it.

Resources