From Olof.Frahm at web.de Thu Apr 15 22:39:13 2010 From: Olof.Frahm at web.de (Olof-Joachim Frahm) Date: Fri, 16 Apr 2010 00:39:13 +0200 Subject: [cl-gtk2-devel] Subclassing GtkWidget Message-ID: <877ho8qr1q.fsf@straylight.rentiernetz> Hi, the title says it: I'm having problems trying to understand how to create a subclass of a widget. In C the corresponding code would set the class methods like > widget_class->realize = ... etc. and in python one'd implement the corresponding methods, so what do I have to implement to achieve this? Looking through the source code and following the todo list on the project page I'm currently assuming that the necessary definitions are not yet complete (?) and although for example I've successfully adapted the native GtkTreeModel implementation for my own data model, I'm a bit at loss how to proceed here. So what would help me are some directions either what macros/definitions to use, or what parts need to be implemented to get native widgets, so I could contribute there. Thanks for any suggestions, Olof -- The world is burning. Run. From mathrick at gmail.com Thu Apr 15 23:20:45 2010 From: mathrick at gmail.com (Maciej Katafiasz) Date: Fri, 16 Apr 2010 01:20:45 +0200 Subject: [cl-gtk2-devel] Subclassing GtkWidget In-Reply-To: <877ho8qr1q.fsf@straylight.rentiernetz> References: <877ho8qr1q.fsf@straylight.rentiernetz> Message-ID: On Fri, Apr 16, 2010 at 00:39, Olof-Joachim Frahm wrote: > Hi, the title says it: I'm having problems trying to understand how to > create a subclass of a widget. ?In C the corresponding code would set > the class methods like >> widget_class->realize = ... > etc. and in python one'd implement the corresponding methods, so what do > I have to implement to achieve this? > > Looking through the source code and following the todo list on the > project page I'm currently assuming that the necessary definitions are > not yet complete (?) and although for example I've successfully adapted > the native GtkTreeModel implementation for my own data model, I'm a bit > at loss how to proceed here. > > So what would help me are some directions either what macros/definitions > to use, or what parts need to be implemented to get native widgets, so I > could contribute there. Indeed, that area is not yet complete. I've implemented parts of what's needed[1], though that's also very incomplete and is currently pending a refactoring to use proper meta-mechanisms such as custom GF implementations and method combinations. With the naive approach of throwing macros at it I took initially, you run very quickly into a horrible mess when trying to call C methods on custom objects from Lisp and vice-versa. The problems arise at the boundary between C and Lisp parts of the object's implementation, and are partially caused by the lack of strict rules by which C GObjects are allowed to play, making it tricky to implement the necessary Lisp-side glue. A proper support for gobject-introspection is necessary to make things truly good, but even then there are some unsolved issues when implementing GObjects in Lisp, such as the fact that the calling context is lost when the execution dives into the C side, making it possible and likely that infinite calling loops could be created when trying to resolve the proper calling order for methods. Another is that some code, like GooCanvas, does unorthodox things along the lines of deciding which method to call based on whether the appropriate vtable slot is NULL in the class structure, making it impossible to implement Lisp stubs properly. It will need some heavy thinking before it's anywhere near being generically usable. But for now, feel free to take a look at my code. Generating Lisp stubs works pretty well, calling arbitrary GObject methods doesn't. CALL-NEXT-GMETHOD is where the mess I mentioned lives. If you have any questions, feel free to ask. I'm not actively working on it right now, but I'll be happy to help and do intend to revisit it eventually. [1]http://github.com/mathrick/cl-gtk2 From tkpapp at gmail.com Sat Apr 17 13:30:59 2010 From: tkpapp at gmail.com (Tamas Papp) Date: Sat, 17 Apr 2010 15:30:59 +0200 Subject: [cl-gtk2-devel] how to make non-resizable window? Message-ID: <20100417133059.GA14202@daedalus> Hi, How can I make a window with a fixed size (ie non-resizable?) If I add a :resizable nil to (gtk:let-ui (gtk:gtk-window :var window :title title :default-width width :default-height height :type :toplevel) the window is created (it shows up in my gnome bottom panel) but is not visible/shown. Thanks, Tamas From aerique at xs4all.nl Sat Apr 17 18:06:53 2010 From: aerique at xs4all.nl (Erik Winkels) Date: Sat, 17 Apr 2010 20:06:53 +0200 Subject: [cl-gtk2-devel] how to make non-resizable window? In-Reply-To: <20100417133059.GA14202@daedalus> References: <20100417133059.GA14202@daedalus> Message-ID: <4BC9F8BD.60305@xs4all.nl> Tamas Papp wrote: > > How can I make a window with a fixed size (ie non-resizable?) A perhaps unsatisfactory answer (I don't have a better one for you) would be to try building your GUI with Glade and see if that solves the issue. From Olof.Frahm at web.de Sat Apr 17 18:57:39 2010 From: Olof.Frahm at web.de (Olof-Joachim Frahm) Date: Sat, 17 Apr 2010 20:57:39 +0200 Subject: [cl-gtk2-devel] how to make non-resizable window? In-Reply-To: <20100417133059.GA14202@daedalus> (sfid-20100417_164653_452246_FFFFFFFFC38BA8B9) (Tamas Papp's message of "Sat, 17 Apr 2010 15:30:59 +0200") References: <20100417133059.GA14202@daedalus> Message-ID: <87sk6tx5y4.fsf@straylight.rentiernetz> (Meh, that should've gone here in the first place.) Hi Tamas, Tamas Papp writes: > How can I make a window with a fixed size (ie non-resizable?) If I > add a :resizable nil that's basically right, but since no widget is contained, the window will be resized automatically to 0x0, so either use :width-request and :height-request (or (setf (width-request ...))) or pack something into the window. For example: > (defun foo (&optional (title "Title") (width 640) (height 480)) > (within-main-loop > (let-ui (gtk-window > :var window > :title title > :default-width width > :default-height height > :type :toplevel > :resizable nil > :width-request width > :height-request height) > (widget-show window)))) Cheers, Olof From tkpapp at gmail.com Tue Apr 20 17:30:56 2010 From: tkpapp at gmail.com (Tamas Papp) Date: Tue, 20 Apr 2010 19:30:56 +0200 Subject: [cl-gtk2-devel] possible bug: pointer slot added to all classes by cl-gtk2 Message-ID: <20100420173056.GA2449@daedalus> Hi, After I load cl-gtk2-gtk, a POINTER slot is added to all classes, not just cl-gtk2 classes. Eg if in SLIME I type C-c C-s after (defclass foo () ()) (make-instance 'foo I get (make-instance 'foo initargs... :pointer pointer) This may have something to do with MOP, but I don't know enough to debug it. It would be nice if this could be fixed, it is a minor annoyance. If that matters, I am using the latest cl-gtk2 from the repository, and SBCL 1.0.37.47. Thanks, Tamas From kalyanov.dmitry at gmail.com Tue Apr 20 17:51:23 2010 From: kalyanov.dmitry at gmail.com (Kalyanov Dmitry) Date: Tue, 20 Apr 2010 21:51:23 +0400 Subject: [cl-gtk2-devel] possible bug: pointer slot added to all classes by cl-gtk2 In-Reply-To: <20100420173056.GA2449@daedalus> References: <20100420173056.GA2449@daedalus> Message-ID: <201004202151.37676.Kalyanov.Dmitry@gmail.com> On Tuesday 20 April 2010 21:30:56, Tamas Papp wrote: > Hi, > > After I load cl-gtk2-gtk, a POINTER slot is added to all classes, not > just cl-gtk2 classes. Eg if in SLIME I type C-c C-s after > > (defclass foo () ()) > (make-instance 'foo > > I get > > (make-instance 'foo initargs... :pointer pointer) > > This may have something to do with MOP, but I don't know enough to > debug it. It would be nice if this could be fixed, it is a minor > annoyance. If that matters, I am using the latest cl-gtk2 from the > repository, and SBCL 1.0.37.47. cl-gtk2 does not add poiner slot to any class except its own (e.g., call (closer-mop:class-slots (find-class 'foo)) - the pointer slot won't be there). SLIME arglist for make-instance is wrong in this case. This might be because cl-gtk2 defines methods on make-instance and initialize-instance that accept the :pointer keyword argument and it somehow confuses slime. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: This is a digitally signed message part. URL: From tkpapp at gmail.com Wed Apr 21 08:50:47 2010 From: tkpapp at gmail.com (Tamas Papp) Date: Wed, 21 Apr 2010 10:50:47 +0200 Subject: [cl-gtk2-devel] how to send messages to a window? Message-ID: <20100421085047.GA14132@daedalus> Hi, How can I send an "expose" message to a window from _outside_ the main loop? I need this for the following: I have a Cairo xlib image surface on which I am drawing. Whenever the window needs to be repainted (configure/expose events), the contents of the xlib image surface are copied onto the window. But I need the window to be manually updated whenever I have drawn something new on it (basically, I am drawing from the REPL). I have tried the following: I save the widget created by GTK2 as a slot in a class (cairo-drawing-area), and whenever the surface is drawn on, this method is called automatically: (defmethod sync ((object gtk2-xlib-context)) (gtk:within-main-loop (with-slots (sync-counter cairo-drawing-area) object (when (zerop sync-counter) (repaint-drawing-area cairo-drawing-area))))) The function inside is (defun repaint-drawing-area (widget) (cl-gtk2-cairo:with-gdk-context (target-context (gtk:widget-window widget)) (set-source-surface (source-surface widget) 0 0 target-context) (paint target-context))) When called by GTK2, it works: (defmethod initialize-instance :after ((w cairo-drawing-area) &rest initargs) (declare (ignore initargs)) (gobject:connect-signal w "configure-event" (lambda (widget event) (declare (ignore event)) (repaint-drawing-area widget))) (gobject:connect-signal w "expose-event" (lambda (widget event) (declare (ignore event)) (repaint-drawing-area widget)))) But when I call sync, sometimes I get "unmapped memory area" errors for GObject callbacks. The whole code is available here: http://github.com/tpapp/cl-cairo2/tree/master/src/gtk2/ Thanks, Tamas From mathrick at gmail.com Wed Apr 21 09:41:49 2010 From: mathrick at gmail.com (Maciej Katafiasz) Date: Wed, 21 Apr 2010 11:41:49 +0200 Subject: [cl-gtk2-devel] how to send messages to a window? In-Reply-To: <20100421085047.GA14132@daedalus> References: <20100421085047.GA14132@daedalus> Message-ID: On Wed, Apr 21, 2010 at 10:50, Tamas Papp wrote: > How can I send an "expose" message to a window from _outside_ the main > loop? You can't. Not in the GTK+ terms, anyway. GTK+ windows don't have "messages", and you don't "send" anything. These are Win32 terms, and you're probably confusing yourself because there it is indeed possible to send messages to foreign windows (and deadlock spectacularly because as soon as you do, you get multiple threads waiting on each other, and that's never pretty). Now, you need to explain how you got outside of the main loop. Is it another thread? If so, don't do it, it *will* break and is wrong. Add a new event source to the loop and make it take input from an async queue, which you'll feed from the other thread. Or just add make an idle function to the loop which will fire repaint in response to new events deposited in the queue, without making it an event source, if it's too much complexity for your needs. If what you want to send events from is completely external to your process, then the easiest way should be just to trigger plain X expose events on the window. That goes outside of the scope of GTK+, and I'm not familiar with X enough to tell you off-hand how to do it, but I seem to recall there were enough low-level X bits wrapped in GDK that it should be doable. Cheers, Maciej From Olof.Frahm at web.de Wed Apr 21 14:17:14 2010 From: Olof.Frahm at web.de (Olof-Joachim Frahm) Date: Wed, 21 Apr 2010 16:17:14 +0200 Subject: [cl-gtk2-devel] UNS: how to send messages to a window? In-Reply-To: <20100421085047.GA14132@daedalus> (sfid-20100421_150055_638995_BCEB7EC5) (Tamas Papp's message of "Wed, 21 Apr 2010 10:50:47 +0200") References: <20100421085047.GA14132@daedalus> Message-ID: <87tyr4ubyt.fsf@straylight.rentiernetz> Tamas Papp writes: > I need this for the following: I have a Cairo xlib image surface on > which I am drawing. Whenever the window needs to be repainted > (configure/expose events), the contents of the xlib image surface are > copied onto the window. But I need the window to be manually updated > whenever I have drawn something new on it (basically, I am drawing > from the REPL). When I tried that (drawing from the REPL), I didn't seem like repainting was necessary, but maybe that has something to do with my remote X connection ... > But when I call sync, sometimes I get "unmapped memory area" errors > for GObject callbacks. The whole code is available here: > http://github.com/tpapp/cl-cairo2/tree/master/src/gtk2/ For what it's worth: trying the code from the repo above, I don't get any errors; e.g. when I: > (dotimes (i 50) (sync *context*)) . Also, to schedule the repaint with WITHIN-MAIN-LOOP sounds good to me since every access then still comes from the GTK main loop ... Regarding generating expose events/repainting: something like > (gtk:within-main-loop > (set-source-color cl-colors:+blue+) > (move-to 300 200) > (line-to 200 300) > (stroke) > (repaint-drawing-area (slot-value *context* 'cairo-drawing-area))) as described in [1] should to the trick. And now just a guess, but does this change anything (returning a boolean value): > (defmethod initialize-instance :after ((w cairo-drawing-area) &rest initargs) > (declare (ignore initargs)) > (gobject:connect-signal w "configure-event" > (lambda (widget event) > (declare (ignore event)) > (repaint-drawing-area widget) > T)) > (gobject:connect-signal w "expose-event" > (lambda (widget event) > (declare (ignore event)) > (repaint-drawing-area widget) > T))) HTH and maybe with some testing I'll see that error too, Olof [1]: http://library.gnome.org/devel/gtk/stable/GtkWidget.html#gtk-widget-queue-draw -- The world is burning. Run. From kalyanov.dmitry at gmail.com Wed Apr 21 18:04:57 2010 From: kalyanov.dmitry at gmail.com (Kalyanov Dmitry) Date: Wed, 21 Apr 2010 22:04:57 +0400 Subject: [cl-gtk2-devel] how to send messages to a window? In-Reply-To: <20100421085047.GA14132@daedalus> References: <20100421085047.GA14132@daedalus> Message-ID: <201004212205.04390.Kalyanov.Dmitry@gmail.com> On Wednesday 21 April 2010 12:50:47, Tamas Papp wrote: > Hi, > > How can I send an "expose" message to a window from _outside_ the main > loop? Basically, you can't. You should call queue-widget-draw function inside main loop by means of within-main-loop-and-wait (this macro will wait until your code actually completes in the main loop and returns its return value) or within-main-loop (this macro will not wait until your code finishes or even starts executing and returns immediately). Call to this function marks the widget area as invalidated and at the next occasion (at the next iteration of gtk+ event loop) Gtk+ will repaint the widget. > But when I call sync, sometimes I get "unmapped memory area" errors > for GObject callbacks. The whole code is available here: > http://github.com/tpapp/cl-cairo2/tree/master/src/gtk2/ Could you provide more information, a stack trace? Where does this message comes from - is it a Lisp exception or cairo error message or gtk error message? Does it occur randomly or deterministically? The code looks fine except for several issues: 1) in create-gtk2-xlib-context you can use within-main-loop-and-wait instead of within-main-loop 2) (incf (sync-counter-object)) is not atomic - you should use a real lock (bordeaux-threads provides portable locking API) -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: This is a digitally signed message part. URL: From tkpapp at gmail.com Thu Apr 22 15:13:21 2010 From: tkpapp at gmail.com (Tamas Papp) Date: Thu, 22 Apr 2010 17:13:21 +0200 Subject: [cl-gtk2-devel] how to send messages to a window? In-Reply-To: <201004212205.04390.Kalyanov.Dmitry@gmail.com> References: <20100421085047.GA14132@daedalus> <201004212205.04390.Kalyanov.Dmitry@gmail.com> Message-ID: <20100422151321.GA1755@daedalus> On Wed, 21 Apr 2010, Kalyanov Dmitry wrote: > On Wednesday 21 April 2010 12:50:47, Tamas Papp wrote: > > Hi, > > > > How can I send an "expose" message to a window from _outside_ the main > > loop? > > Basically, you can't. You should call queue-widget-draw function inside main > loop by means of within-main-loop-and-wait (this macro will wait until your > code actually completes in the main loop and returns its return value) or > within-main-loop (this macro will not wait until your code finishes or even > starts executing and returns immediately). Call to this function marks the > widget area as invalidated and at the next occasion (at the next iteration of > gtk+ event loop) Gtk+ will repaint the widget. Thanks, that's what I am doing now. > > But when I call sync, sometimes I get "unmapped memory area" errors > > for GObject callbacks. The whole code is available here: > > http://github.com/tpapp/cl-cairo2/tree/master/src/gtk2/ > > Could you provide more information, a stack trace? Where does this message > comes from - is it a Lisp exception or cairo error message or gtk error > message? Does it occur randomly or deterministically? This is a Lisp exception, occurring randomly. Backtrace is here: Unhandled memory fault at #x40. [Condition of type SB-SYS:MEMORY-FAULT-ERROR] Restarts: 0: [RETURN-FROM-G-CLOSURE] Return value from closure 1: [RETURN-FROM-CALLBACK] GTK::RETURN-FROM-CALLBACK 2: [TERMINATE-THREAD] Terminate this thread (#) Backtrace: 0: (SB-SYS:MEMORY-FAULT-ERROR) [No Locals] 1: ("foreign function: #x422670") [No Locals] 2: ("foreign function: #x422750") [No Locals] 3: ("foreign function: #x802837D7D8") [No Locals] 4: (CL-CAIRO2::REPAINT-DRAWING-AREA #) Locals: SB-DEBUG::ARG-0 = # 5: (GOBJECT::CALL-WITH-RESTARTS ..) Locals: SB-DEBUG::ARG-0 = # SB-DEBUG::ARG-1 = (# ..) 6: ((LAMBDA (GOBJECT::CLOSURE GOBJECT::RETURN-VALUE GOBJECT::COUNT-OF-ARGS GOBJECT::ARGS GOBJECT::INVOCATION-HINT GOBJECT::MARSHAL-DATA)) ..) Locals: SB-DEBUG::ARG-0 = #.(SB-SYS:INT-SAP #X0070ACB0) SB-DEBUG::ARG-1 = #.(SB-SYS:INT-SAP #X7FFFE9C6AD20) SB-DEBUG::ARG-2 = 2 SB-DEBUG::ARG-3 = #.(SB-SYS:INT-SAP #X0070A410) SB-DEBUG::ARG-4 = : SB-DEBUG::ARG-5 = : 7: ((LAMBDA (SB-ALIEN::ARGS-POINTER SB-ALIEN::RESULT-POINTER FUNCTION)) 17592139437423 17592139437422 #) Locals: SB-DEBUG::ARG-0 = 17592139437423 SB-DEBUG::ARG-1 = 17592139437422 SB-DEBUG::ARG-2 = # 8: ("foreign function: #x422670") 9: ("foreign function: #x40CFB0") 10: ("foreign function: #x20101234") 11: ("foreign function: #x8016E59B08") 12: ((LAMBDA (SB-ALIEN::ARGS-POINTER SB-ALIEN::RESULT-POINTER FUNCTION)) 17592139438208 17592139438207 #) 13: ("foreign function: #x422670") 14: ("foreign function: #x40CFB0") 15: ("foreign function: #x20101B1B") 16: ("foreign function: #x803CFDF088") 17: ((LAMBDA ())) 18: ((FLET #:WITHOUT-INTERRUPTS-BODY-[BLOCK369]374)) 19: ((FLET SB-THREAD::WITH-MUTEX-THUNK)) 20: ((FLET #:WITHOUT-INTERRUPTS-BODY-[CALL-WITH-MUTEX]300)) 21: (SB-THREAD::CALL-WITH-MUTEX ..) 22: (SB-THREAD::INITIAL-THREAD-FUNCTION) 23: ("foreign function: #x422670") 24: ("foreign function: #x419307") > The code looks fine except for several issues: > 1) in create-gtk2-xlib-context you can use within-main-loop-and-wait instead > of within-main-loop > 2) (incf (sync-counter-object)) is not atomic - you should use a real lock > (bordeaux-threads provides portable locking API) Thanks for the hints. Tamas