Drawing in GtkTextView, then clearing - c

I simply draw specific content in a GtkTextView in a 'draw' signal,
on a next signal emission I draw different things in GtkTextView.
In the next signal invocation, if there is nothing to be drawn it clears all the previous drawings, which is good.
But when it is about to draw the new content, it draws all the previous at once, not only the needed one. Which is no good.
I tried many things to prevent this behavior, every possible combination with cairo_save() and cairo_restore() don't seem to do it.
How can I make it not draw every previous drawing at once, but the new one only ?

The "draw" signal should be only used to change GtkTextView's constant appearance.
For what I want, this may work as requested:
void draw_on_textview (GtkWidget* textview)
{
cairo_t* cr = gdk_cairo_create(gtk_widget_get_window(textview));
// Do ALL the drawing AT ONCE here..
cairo_destroy(cr);
}
When content needs to be removed:
gtk_widget_queue_draw(textview);
However this is still slightly different than the appropriate approach. As #jcoppens stated, draw_layer must be used instead. So I don't count this as an answer but some possible approach that I could alternatively use if there is no one else to provide the better way.

Related

gtk drawing area does not redraw content

I am on an Ubuntu 19.10 64 bit system
Source files:
https://drive.google.com/open?id=1I4ejOHNXqbAOkTbIyJR0lvldsAwiPPqI
Problem:
I am working on a simple drawing program using gtk and glade with c. Right now I am stuck into implementing undoing behavior. I have two problems. There are cases for when I press the undo button.
1)
When I have one stroke or one dot on the canvas, it works perfect as I experienced. Canvas clears itself.
2)
When I have two strokes or two dots on the canvas, if I click undo once, canvas does not redraw itself, unless I draw again; if I click twice, it works perfect like in the first case, canvas clears.
3)
When I have more than two strokes or two dots on the canvas, if I click undo twice, the program stops working waiting me to force quit.
I am a beginner at using glade, gtk3, and cairo libraries. I have been searching about the issue for days. However, the resources are scarce compared to trending frameworks and libraries. Furthermore, I couldn't match the problem I need. I appreciate any help.
EDIT I forgot to add that the halting problem occurs after the function , on_undo_clicked exits the second time (twice undo click).
I solved the problem.
In the function, addPoint I forgot that the next struct pointer's pre pointer may be a dangling pointer. It creates the problem.

Xlib - Two issues with call to XMoveResizeWindow

I am new to Xlib (in C) and am having two issues when calling the XMoveResizeWindow function.
ex.
XMoveResizeWindow(display, window_id, move_x, move_y, resize_x, resize_y);
1) After the call, the window I move will reposition itself correctly, however, if I select the window with the pointer after the move, it will instantly revert back to the position it held prior to the move. I assume I have to somehow 'update' the X11 server after it's moved with the windows new position?
2) Secondly, in regards to the resize of the window. My window is essentially being truncated by the x and y values entered, instead of resized. In other words, instead of the entire window shrinking down, the right and bottom sides of the window are cut off from view. Is there a way to instead resize the entire window?
--I am sorry I am unable to submit my complete code, however, I believe my issues are due solely to my lack of understanding of Xlib and this particular function's operations. As such, I am not neccessarily looking for specific code as a solution, merely an explination or suggestion on how I should go about implementing a solution.
Thank you.
I believe there is something wrong with your code, since that code is not available i'll point to an example.
Examples are given at readme itself.

How do I determine non-rectangular drawing regions in Gtk+ 3 with cairo?

The Gtk+ 3 migration guide shows how the GdkEventExpose.region field can be used to provide a fine-grained area for re-rendering widgets. We already do something like this in Inkscape to avoid rendering excessive amounts of complicated stuff on our drawing canvas.
However, the example in the guide shows how to do this for the old Gtk+ 2 expose_event handler.
How do I do the equivalent in a new Gtk+ 3 draw handler, which receives a "ready-clipped" Cairo context as a parameter, rather than a GdkEventExpose?
I guess one possibility is to use cairo_copy_clip_rectangle_list on the "ready-clipped" cairo context to obtain a list of rectangles that make up the region to draw. Does anyone have any experience of using this? Does it seem like a sensible approach?
Yes, you should use cairo_copy_clip_rectangle_list() on the cairo_t that you get in your widget's ::draw() signal handler. See this commit for an example:
http://git.gnome.org/browse/vte/commit/?id=21a064ac8b5925108b0ab9bd6516664c8cd3e268
Since I have not much clue, I decided to check the source code. GDK emits a GDK_EXPOSE event on a window and creates the GdkEventExpose instance for this.
This event is then handled in gtk/gtkmain.c via gtk_widget_send_expose():
http://git.gnome.org/browse/gtk+/tree/gtk/gtkwidget.c?id=eecb9607a5c0ee38eadb446545beccd0922cb0b8#n6104
This function clips the cairo_t to GdkEventExpose.region, as you already learned in the docs.
This then calls _gtk_widget_draw_internal() which emits the actual draw signal:
http://git.gnome.org/browse/gtk+/tree/gtk/gtkwidget.c?id=eecb9607a5c0ee38eadb446545beccd0922cb0b8#n5726
As far as I can see, nothing here let's you access the clip region directly. In gtk_widget_send_expose() the GdkEvent is added as userdata to the cairo context. However, this is not accessible, because all the involved functions and variables are static. So you'll have to use cairo_copy_clip_rectangle_list().
However, this sounds quite inefficent. First gdk_cairo_region transforms the region into a number of calls to cairo_rectangle and then cairo transforms this from its internal representation into a cairo_rectangle_list_t (which may fail if the clip is, for some reason, not a region). If you see this being slow, it might make sense to have some shortcut for this added to gtk directly.

Clearing the screen causes a flicker due to no frame back buffer

Hey guys I am programming for a primitive type board using some assembly and C, consider the board to be aKin to the old school black and white gameboy.
I am running into a problem while writing a game in that there is no backbuffer. when I clear the screen it draws directly to the screen so that the screen truly is cleared, and thus makes anything I draw invisible, because it is immediately cleared in the next pass. So instead of replacing a drawn screen with a new drawn screen, it clears the screen then draws it.
I came up with a hackish solution in where I Limited the rendering to 10 frames per second.
The way I do this is by clearing the screen, drawing the shape, and then burning a loop for however long remains in the 1/10th second. This way whatever is drawn will stay there longer, and be visible longer, allowing the user to see it before it is immediately erased.
i.e.
while (1)
{
doRender = 1;
screen_clear();
draw_circle(x,y,20,1);
while(doRender)
{
// a interrupt will set doRender to 0, thus ending the loop
}
}
This works!! sort of, it creates a flicker, not horrible, but noticeable to be sure. My game does not require incredible framerates, 10/sec will do.
Does anyone have a better solution to my issue?
Your solution is good. Try optimize it by clearing only the area where the circle has been drawn.
You can also use XOR rendering. E.g: you XOR your sprite to the screen to render it, then on the next frame XOR it again at the same place to remove it and XOR it in its new place.
Can you wait for the vsync? If your drawing is fast enough, you may be able to do it during the vertical blank interval, removing any remaining flicker.

GTK: Get pointer position on scroll-event AFTER scrolled_window has scrolled

I've got a drawing area inside a scrolled window (with convenience viewport),
and this drawing area updates itself according to incoming motion-notify-events.
When I scroll the area though obviously no motion events are emitted,
but I wanted to work around this, and so tried to connect the drawing area's
"scroll-event" signal to the same motion-notify callback.
The problem I'm facing here is that this signal is emitted before the scrolled window
has update its viewport, so in the callback, I end up with pointer coordinates that were true just before scrolling, making it look like the drawing area is always "lagging a step behind" the actual pointer when scrolling while not moving the pointer itself.
I thought I could compensate for this by manually extracting the coordinates with gdk_window_get_pointer, but then I realized this cannot work as the pointer is technically still at its old position when the callback is commencing.
I also tried using g_signal_connect_after in hopes it would have the callback get called after the viewport was scrolled, but it didn't help.
My last hope would be to start a timer on scroll-events, and have the callback fire after a minimal amount of time, but this sounds realllly ugly, and I'd like to avoid that at any cost.
Any ideas as to how this could be realized?
Thanks in advance!
A solution would be to connect to the "value-changed" signal of the GtkScrolledWindow
adjustments.
Source: https://mail.gnome.org/archives/gtk-app-devel-list/2011-September/msg00014.html

Resources