# Identify button modifiers in Gtk

**URL:** <https://discourse.julialang.org/t/identify-button-modifiers-in-gtk/9411>\
**Category:** General Usage\
**Tags:** question, guis\
**Created:** [March 1, 2018, 10:42am UTC](https://discourse.julialang.org/t/identify-button-modifiers-in-gtk/9411 "2018-03-01T10:42:44Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [March 1, 2018, 10:42am UTC](https://discourse.julialang.org/t/identify-button-modifiers-in-gtk/9411/1 "2018-03-01T10:42:44Z")

</div>

**tl;dr:** _How can I reliably test which modifier a user is pressing while clicking the mouse?_

I’m using `ImageView.imshow` as a GUI to select points on an image. The functionalities already baked-in in `imshow` (zoom, pan, annotate) are the main reason why I’m hijacking that structure. But I need to add some way for the user to pick (and un-pick) a point on the displayed image. To do that I’ve used the [drawing example in `GtkReactive`](https://github.com/JuliaGizmos/GtkReactive.jl/blob/8179c208ff5fa16d6d4879c8dce578cc68eff59b/examples/drawing.jl#L12):

```julia
sigstart = map(c.mouse.buttonpress) do btn
    if btn.button == 1
        if btn.modifiers == 1 #shift
            push!(add, btn.position)
        elseif btn.modifiers == 5 #shift+ctrl
            push!(remove, btn.position)
        end
    end
end

```

where `add` and `remove` are signals that add or remove the coordinate from the list of chosen coordinates.

My problem is that `Shift` and `Ctrl-Shift` are not always 1 and 5 respectively (i.e. I sometimes get 16 and 17). I have no idea what governs this fickleness, but it means that I can’t use _that_ as a mechanism to identify which modifiers the user pressed. I have tried to pry-out the way this is accomplished in `ImageView.imshow` (e.g. the users can press `Ctrl` with the scroll wheel to zoom), but without any success. Even trying to compare `btn.button` to `GtkReactive.SHIFT` didn’t work…

Anyone knows how to do this from within Julia (i.e. I’m not any wiser from reading the [`Gtk` manual about modifiers](https://developer.gnome.org/gtk3/stable/checklist-modifiers.html))?

---

<div class="post-metadata">

**Author:** ![y4lu](https://avatars.discourse-cdn.com/v4/letter/y/47e85d/32.png) [@y4lu](https://discourse.julialang.org/u/y4lu)\
**Post date:** [March 1, 2018, 11:53am UTC](https://discourse.julialang.org/t/identify-button-modifiers-in-gtk/9411/2 "2018-03-01T11:53:16Z")

</div>

btn.Modifiers is using bit-valued flags, so each flag is one of 2^0 to 2^x and they’re just added together into one value  
`x & 0x01 == 0x01` is the shift key, which is the same as ` x & 1 == 1, x & 4 == 0x04` would be the control key, alt or another would be 16

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [March 1, 2018, 12:21pm UTC](https://discourse.julialang.org/t/identify-button-modifiers-in-gtk/9411/3 "2018-03-01T12:21:46Z")

</div>

Thanks @y4lu! I hope I understood you correctly. This:

```julia
    sigstart = map(c.mouse.buttonpress) do btn
        if btn.button == 1
            if btn.modifiers & 0x01 == 0x01 #shift
                push!(add, btn.position)
            elseif btn.modifiers & 0x04 == 0x04 # ctrl
                push!(remove, btn.position)
            end
        end
    end

```

seems to be working! I couldn’t quite figure out how to test for if both the `Shift` _and_ `Ctrl` are pressed together, but I’m willing to live with this (since it seems to not collide with the `Ctrl` zoom of `imshow`).  
Thanks again!

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [March 1, 2018, 12:30pm UTC](https://discourse.julialang.org/t/identify-button-modifiers-in-gtk/9411/4 "2018-03-01T12:30:26Z")

</div>

Both of those can be true at the same time – IIUC `Ctrl` and `Shift` together will give you `0x05`, for which

```julia
julia> 0x05 & 0x04 == 0x04 && 0x05 & 0x01 == 0x01
true

```

Also check the bit representation via `bits`.

---

<div class="post-metadata">

**Author:** ![jonathanBieler](https://avatars.discourse-cdn.com/v4/letter/j/82dd89/32.png) [@jonathanBieler](https://discourse.julialang.org/u/jonathanBieler)\
**Post date:** [March 1, 2018, 12:32pm UTC](https://discourse.julialang.org/t/identify-button-modifiers-in-gtk/9411/5 "2018-03-01T12:32:58Z")

</div>

Ideally you have to use `gtk_accelerator_get_default_mod_mask` to get the mask, to deal with caps lock and such.

I made a PR about this a while ago:

[https://github.com/JuliaGraphics/Gtk.jl/pull/310/files](https://github.com/JuliaGraphics/Gtk.jl/pull/310/files)

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [March 1, 2018, 12:36pm UTC](https://discourse.julialang.org/t/identify-button-modifiers-in-gtk/9411/6 "2018-03-01T12:36:04Z")

</div>

Omg, that’s almost a year ago. Too bad, this sounds awesome. I left a message there.

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [March 1, 2018, 12:43pm UTC](https://discourse.julialang.org/t/identify-button-modifiers-in-gtk/9411/7 "2018-03-01T12:43:46Z")

</div>

> [@pfitzseb](#):
>
> Both of those can be true at the same time – IIUC Ctrl and Shift together will give you 0x05, for which

I see, ok, so to get the Shift-Ctrl I did this:

```julia
sigstart = map(c.mouse.buttonpress) do btn
    if btn.button == 1
        if btn.modifiers & 0x01 == 0x01 # Shift and
            if btn.modifiers & 0x04 == 0x04 # Ctrl
                push!(remove, btn.position)
            else # anything really
                push!(add, btn.position)
            end
        end
    end
end

```
