I try to handle scroll events on an Gtk::StatusIcon. I woulld like to do
somehing like that
#!/usr/bin/env ruby
###call this script with one argument (a path to an image).
require 'gtk2'
si=Gtk::StatusIcon.new
si.pixbuf=Gdk::Pixbuf.new(ARGV[0])
si.signal_connect('scroll-event'){|icon, event|
p event.state
p event.state.to_i
case event.state
when 0#Empty mask
p 'scroll event'
p event.direction
when Gdk::Window::CONTROL_MASK
p 'control+scroll event'
end
}
Gtk.main
On my latop, I did not work.
If I use ctrl+scroll, event.state.inspect shows a control mask type but
event.state.to_i==8196 or Gdk::Window::CONTROL_MASK.to_i==4. Apparently
the 14th bit of event.state is equal to 1.
http://library.gnome.org/devel/gdk/unstable/gdk-Windows.html#GdkModifierType
tells nothing about this bit.
Why this bit is 1? Will it always be 1?
I could use event.state.inspect and strings in the case statement but it
really seems ugly.
I do not know what to do.
on 2009-12-08 22:04
on 2009-12-08 23:30
Vincent Carmona wrote: I reread gtk doc. It seems that bits 13 and 14 are used by xkb. For now, I will use a workaround to have bits 13 and 14 equal to 0. b=event.state.to_i.to_s(2) b.reverse!;b[13]=0 if b[13];b[14]=0 if b[14];b.reverse! case b.to_i(2) when 0 ... when Gdk::Window::CONTROL_MASK ... end Not very clean but it does not rely on the output of inspect method.
on 2009-12-09 12:32
2009/12/8 Vincent Carmona <ruby-forum-incoming@andreas-s.net>: > ... > end > I think you do not understand how masks should be used. Here is a working example : #!/usr/bin/env ruby #call this script with one argument (a path to an image). require 'gtk2' si = Gtk::StatusIcon.new si.pixbuf = Gdk::Pixbuf.new(ARGV[0]) si.signal_connect('scroll-event') do |icon, event| p event.state p event.direction case when (event.state & Gdk::Window::CONTROL_MASK) != 0 p 'control + scroll event' when (event.state & Gdk::Window::SHIFT_MASK) != 0 p 'shift + scroll event' else p 'scroll only' end end Gtk.main It works for me. I always have #<Gdk::Window::ModifierType mod2-mask>, which seems to be "numlock". If you do not want to manage control/shift/alt, you don't really care about it, since you only need direction. Hope it helps. Simon
on 2009-12-10 18:24
Hi Simon. Thanks for you reply. I do want manage crontol/shift... since I want to call different actions depending on the modifier used. I understand !(event.state & Gdk::Window::CONTROL_MASK) check if control is hit. But it do not check if control is the only modifier hit. Am I wrong? I think I will have to used a solution close to yours. Cause I cannot be sure none other modifier (num lock, caps lock...) is pressed. event.state.control_mask? should be equal to !(event.state & Gdk::Window::CONTROL_MASK) and it look nicer. :) Thanks for your help. Simon Arnaud wrote: > Here is a working example : > #!/usr/bin/env ruby > #call this script with one argument (a path to an image). > require 'gtk2' > si = Gtk::StatusIcon.new > si.pixbuf = Gdk::Pixbuf.new(ARGV[0]) > si.signal_connect('scroll-event') do |icon, event| > p event.state > p event.direction > case > when (event.state & Gdk::Window::CONTROL_MASK) != 0 > p 'control + scroll event' > when (event.state & Gdk::Window::SHIFT_MASK) != 0 > p 'shift + scroll event' > else > p 'scroll only' > end > end > Gtk.main > > It works for me. I always have #<Gdk::Window::ModifierType mod2-mask>, > which seems to be "numlock". > > If you do not want to manage control/shift/alt, you don't really care > about it, since you only need direction. > > Hope it helps. > > Simon
on 2009-12-11 11:03
2009/12/10 Vincent Carmona <ruby-forum-incoming@andreas-s.net>: > I understand !(event.state & Gdk::Window::CONTROL_MASK) check if control > is hit. But it do not check if control is the only modifier hit. > Am I wrong? You are right, my example was to show you how to use bitmask. It is not functional :). I don't know of syntactic sugar for bitmasks in ruby, so you have to program almost like in C. > I think I will have to used a solution close to yours. Cause I cannot be > sure none other modifier (num lock, caps lock...) is pressed. > event.state.control_mask? should be equal to !(event.state & > Gdk::Window::CONTROL_MASK) and it look nicer. :) I don't think you need to know what other controls are on or off, you already know you are in a scroll event, just check the modifier you want to manage (ctrl, shift, alt, whatever). If you want to manage ctrl, shift, and ctrl+shift, it would be something like this: if (event.state & Gdk::Window::CONTROL_MASK) then code elif (event.state & Gdk::Window::SHIFT_MASK) then code elif (event.state & (Gdk::Window::CONTROL_MASK|Gdk::Window::SHIFT_MASK)) then code else code end you could use an empty case also. Simon
on 2009-12-11 11:46
I am currently tring this code : mask=0; mod=event.state mask+=1 if mod.control_mask?# 1==2**0 mask+=2 if mod.shift_mask?# 2==2**1 mask+=4 if mod.mod1_mask?#Alt 4=2**2 case mask when 0 code when 1 code when 2 code when 3 code ... end It look very similar to yours. Instead of checking the bit mask, I use a integer corresponding to each bit. After all integer are store binary! (Not sure I am very clear) If It does not work, I will try your code. Thanks for your time. Simon Arnaud wrote: > I don't think you need to know what other controls are on or off, you > already know you are in a scroll event, just check the modifier you > want to manage (ctrl, shift, alt, whatever). > > If you want to manage ctrl, shift, and ctrl+shift, it would be > something like this: > if (event.state & Gdk::Window::CONTROL_MASK) then > code > elif (event.state & Gdk::Window::SHIFT_MASK) then > code > elif (event.state & (Gdk::Window::CONTROL_MASK|Gdk::Window::SHIFT_MASK)) > then > code > else > code > end > > you could use an empty case also. > > Simon
on 2009-12-11 11:55
Le vendredi 11 décembre 2009 à 11:02 +0100, Simon Arnaud a écrit : > if (event.state & Gdk::Window::CONTROL_MASK) then > code > elif (event.state & Gdk::Window::SHIFT_MASK) then > code > elif (event.state & (Gdk::Window::CONTROL_MASK|Gdk::Window::SHIFT_MASK)) then This one should be first, else you will never enter it because event.state & Gdk::Window::CONTROL_MASK will be true
on 2009-12-11 12:07
I did not think about that. But of course if (event.state & (Gdk::Window::CONTROL_MASK|Gdk::Window::SHIFT_MASK)) is true, (event.state & Gdk::Window::CONTROL_MASK) is necessarry true. So we should check against (Gdk::Window::CONTROL_MASK|Gdk::Window::SHIFT_MASK) first. Thanks Pascal Terjan for this fine remark. Pascal Terjan wrote: > Le vendredi 11 d�cembre 2009 � 11:02 +0100, Simon Arnaud a �crit : >> if (event.state & Gdk::Window::CONTROL_MASK) then >> code >> elif (event.state & Gdk::Window::SHIFT_MASK) then >> code >> elif (event.state & (Gdk::Window::CONTROL_MASK|Gdk::Window::SHIFT_MASK)) then > > This one should be first, else you will never enter it because > event.state & Gdk::Window::CONTROL_MASK will be true
on 2009-12-11 12:44
2009/12/11 Vincent Carmona <ruby-forum-incoming@andreas-s.net>: > Â code > when 2 > Â code > when 3 > Â code > ... > end > > It look very similar to yours. Instead of checking the bit mask, I use a > integer corresponding to each bit. After all integer are store binary! I did not thought about that. But it's much simpler than you think : mask = event.state & (Gdk::Window::CONTROL_MASK|Gdk::Window::SHIFT_MASK|...) case mask when Gdk::Window::CONTROL_MASK code when Gdk::Window::SHIFT_MASK code when Gdk::Window::CONTROL_MASK|Gdk::Window::SHIFT_MASK code end You could switch to integers, but may gdk changes its mask, very unlikely, but who knows, it would break. Taking out verbosity, the code is much understandable imo with the constants. And thanks Pascal, my exmaple was terrible indeed :) Simon
on 2009-12-11 13:11
If gdk changes its mask, my code should not brake cause the integer is build with control_mask? and co methods. But you are write your last code seems more understable. I think I will rewrite my method. Once again thanks. Simon Arnaud wrote: > mask = event.state & > (Gdk::Window::CONTROL_MASK|Gdk::Window::SHIFT_MASK|...) > case mask > when Gdk::Window::CONTROL_MASK > code > when Gdk::Window::SHIFT_MASK > code > when Gdk::Window::CONTROL_MASK|Gdk::Window::SHIFT_MASK > code > end > > You could switch to integers, but may gdk changes its mask, very > unlikely, but who knows, it would break. > Taking out verbosity, the code is much understandable imo with the > constants. > > And thanks Pascal, my exmaple was terrible indeed :) > > Simon
on 2009-12-12 04:27
Hey, could you show your final version, if you don't mind? I'd like to collect interesting code (such as this) if it is working. :)
on 2009-12-12 21:13
Marc Heiler wrote:
> Hey, could you show your final version, if you don't mind?
I will as soon as it is written.
on 2009-12-13 01:33
My "code with integer" works but I finally use Simon code. #Check only for control, alt and shift. mask=event.state&(Gdk::Window::CONTROL_MASK|Gdk::Window::MOD1_MASK|Gdk::Window::SHIFT_MASK) case mask when 0#no modifier key hit code when Gdk::Window::CONTROL_MASK code when (Gdk::Window::CONTROL_MASK|dk::Window::MOD1_MASK) code ... end It works well on my laptop. Vincent
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.