How to combine "button-press-event" with "key-press-event" To catch ALT + LeftClick (button1)

Like the Title says I will like to know how does ALT + LeftClick signal are handled in GTK applications.

At this point lets say I have the following program:

#include <gtk/gtk.h>

#define EVENTS ( GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK )

gboolean button_pressed_callback ( GtkWindow *window, GdkEventButton  *event );
gboolean alt_plus_key_callback   ( GtkWindow *window, GdkEventKey *event );

int main ( void )
{
    GtkWidget *window;

    /// ***
    gtk_init ( NULL, NULL );

    /// *** Create a Window
    window = gtk_window_new  ( GTK_WINDOW_TOPLEVEL );
    gtk_widget_add_events    ( window, ( gtk_widget_get_events ( window ) | EVENTS  ) );

    /// *** Catch the Signals
    g_signal_connect_swapped ( window, "button-press-event", G_CALLBACK ( button_pressed_callback ), window );
    g_signal_connect_swapped ( window, "key-press-event",    G_CALLBACK ( alt_plus_key_callback ),   window );

    /// ***
    gtk_widget_show_all ( window );
    gtk_main ();
}

gboolean alt_plus_key_callback ( GtkWindow *window, GdkEventKey *event )
{
    if ( GTK_IS_WINDOW ( window ) )
    {
        GdkModifierType modifiers = gtk_accelerator_get_default_mod_mask ();
        if ( ( event->state & modifiers ) == GDK_MOD1_MASK )
        {
                g_print ( "ALT  + a KEY was pressed\n" );
            return TRUE;
        }
    }

    return FALSE;
}

gboolean button_pressed_callback ( GtkWindow *window, GdkEventButton  *event )
{
    if ( GTK_IS_WINDOW ( window ) )
    {
        if ( event->type == GDK_BUTTON_PRESS )
        {
            switch ( event->button )
            {
            case 1:
                g_print ( "Left-Click button was pressed\n" );
                break;
            default:
                break;
            }
        }
        return FALSE;
    }
    return TRUE;
}

Here if one use its mouse left click or press the ALT + SOME_KEY the following Output will come:

Left-Click button was pressed
Left-Click button was pressed
ALT  + a KEY was pressed
ALT  + a KEY was pressed

The Question is, how can I catch both ALT + BUTTON1 (Mouse Left Click) in GTK3?

GTK3,Linux Mint 19.2, GCC-8

The Question is, how can I catch both ALT + BUTTON1 (Mouse Left Click)
in GTK3?
The GdkEventButton [1] you get in the button event has all you need: see
its state member, just like with GdkEventKey.

[1]

2 Likes

I already did that (or at least I hope I did it right) and it is not working.
Did you mean something like this?

gboolean button_pressed_callback ( GtkWindow *window, GdkEventButton  *event )
{
    if ( GTK_IS_WINDOW ( window ) )
    {
        GdkModifierType modifiers = gtk_accelerator_get_default_mod_mask ();
        if ( ( event->state & modifiers ) == GDK_MOD1_MASK )
        {
            if ( event->type == GDK_BUTTON_PRESS )
            {
                if ( event->button == 1 )
                {
                    g_print( "ALT + Left click was pressed\n" );
                }
            }
        }
        return FALSE;
    }
    return TRUE;
}

Because it is not working.

I already did that (or at least I hope I did it right) and it is not
working.
Did you mean something like this?

Yes I do mean this. It work for me, but maybe you have something
stopping this keybinding from reaching your app, like your window
manager? It’s common for window managers to use Alt+LMB to move
windows, Alt+RMB to open the window context menu or Alt+MMB to resize
windows. If that’s the case, I’m afraid I don’t have a solution for you
short of reconfiguring your WM, or changing WM if it’s not possible.

1 Like

Thank you for your fast reply.
It is about “window manager” indeed.
You can check it in this Video right here

I am trying to do 2 things:

1) Catch ALT + LMB ( to print it to the Console)
2) Disable them for my Application if works (programmatically of course).

I need to block the User to use ALT + MOUSE in my Application and printing a message with a warning like this:

ALT + Mouse Left Click are disabled

I am on Linux Mint 19.2 Tina now, probably you are on Windows if you say that it is working in your case.

I would like also an Answer from Gnome (GTK) Team if possible.

This works on Linux as well, it’s not platform specific. A simple example:

import gi
gi.require_version('Gdk', '3.0')
gi.require_version('Gtk', '3.0')
from gi.repository import Gdk, Gtk 

class MyAppWindow(Gtk.ApplicationWindow):
    def __init__(self):
        Gtk.ApplicationWindow.__init__(self)

        self.set_default_size(400, 400)

        self._evbox = Gtk.EventBox()
        self.add(self._evbox)
        self._evbox.show()

        self._evbox.add_events(Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK)
        self._evbox.connect('button-press-event', self._on_button_press)

    def _on_button_press(self, evbox, event):
        print(event)
        print(event.type)
        print(event.get_button())
        print(event.state)

        return False

def on_app_activate(app):
    win = MyAppWindow()
    win.props.application = app 
    win.show()

app = Gtk.Application(application_id='com.example.Test')
app.connect('activate', on_app_activate)
app.run(None)

Will print:

<Gdk.EventButton object at 0x7f5e689d37d0 (void at 0x55e6cf502b40)>
<enum GDK_BUTTON_PRESS of type Gdk.EventType>
(True, button=1)
<flags 0 of type Gdk.ModifierType>

for button press events without the Alt modifier, and will print:

<Gdk.EventButton object at 0x7f5e689d37d0 (void at 0x7f5e6000d520)>
<enum GDK_BUTTON_PRESS of type Gdk.EventType>
(True, button=1)
<flags GDK_MOD1_MASK of type Gdk.ModifierType>

for button press events with the Alt modifier.

Window managers are entirely in charge of soft-grabbing modifiers for their own purposes, and not all of them are careful to replay the event to windows; additionally, applications simply cannot know if a window manager is performing a soft grab on a key sequence. In other words:

cannot be done: you either receive the button press event with a modifier in its state, in which case you can ignore it inside your application; or you won’t receive it at all, even if the user did press Alt when clicking on your window, simply because another component will have swallowed the event.

This is inconsequential: the “GTK Team” is not going to answer all questions on this forum. Other people will, if they know the answer to your question. Or maybe nobody will. This is not a paid user support forum, you are not owed anything.

1 Like

You can check it in this Video right here
https://www.youtube.com/watch?v=2t5-dX248hM&list=PLN_MPJUQgPVoWz_aHqkFS-0NEW6muJM6B&index=6&t=0s

Sorry but I won’t watch a full 17 minutes video right now :slight_smile:

I am trying to do 2 things:

  1. Catch ALT + LMB ( to print it to the Console) 2) Disable them for my
    Application if works (programmatically of course). |

I need to block the User to use ALT + MOUSE in my Application and
printing a message with a warning like this:

ALT + Mouse Left Click are disabled |

Why do you need this? If it’s to prevent users from resizing/moving
your window, it’s not the right approach, as in the best case it will
depend on which WM they are using, and in practice it will never work
because the WM gets the events before the app does, so you can’t block
it that way. If that’s your goal, you should research window attributes
you can use to tell the WM not to allow several things, or run in a
controlled environment where you know the WM and it doesn’t allow this
in the first place.

If the goal is simply not to allow something deeper in your app from
receiving the events for some reason or another, the code you have would
work: either the WM didn’t forward the event, or you’re blocking it.

Finally, FWIW blocking some interaction doesn’t really sound like a
great idea to me, without knowing why you’re trying to achieve in practice.

I am on Linux Mint 19.2 Tina now, probably you are on Windows if you say
that it is working in your case.

I am not, but I can configure my WM to use another key if I want, and it
is set up to use . But indeed if I set it up to use I
don’t get the events anymore – which is to be expected.

1 Like

Sorry for the late replay.
Yes I need to figure out, how to block the user to have control over the application, other than those provided through my application it self.

At this point I use:

gtk_window_set_decorated( GTK_WINDOW ( window ), FALSE);

But this decoration does not help me to STOP the User to use ALT + Keys combinations.
This includes also the right click context menu which is opened with:

ALT + MouseMiddleButton

I would like to know more information about which is the “possible approach” ( if possible ) to isolate the application.

Use gtk_window_set_resizable() to control whether a window is user resizable.

If a window manager still allows resizing unresizable windows then you lose; the window manager is the ultimate arbiter of what can be resizable and what cannot be resized.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.