diff options
Diffstat (limited to 'src/display/sp-canvas.cpp')
| -rw-r--r-- | src/display/sp-canvas.cpp | 178 |
1 files changed, 72 insertions, 106 deletions
diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 7d76fa043..d04c81ecb 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -21,25 +21,30 @@ # include <config.h> #endif +#include <gdkmm/devicemanager.h> +#include <gdkmm/display.h> #include <gdkmm/rectangle.h> #include <cairomm/region.h> #include "helper/sp-marshal.h" #include <2geom/rect.h> #include <2geom/affine.h> -#include "display/cairo-utils.h" #include "display/sp-canvas.h" #include "display/sp-canvas-group.h" +#include "display/rendermode.h" +#include "display/cairo-utils.h" #include "preferences.h" #include "inkscape.h" #include "sodipodi-ctrlrect.h" #include "cms-system.h" -#include "display/rendermode.h" -#include "display/cairo-utils.h" #include "debug/gdk-event-latency-tracker.h" #include "desktop.h" #include "color.h" +#if GTK_CHECK_VERSION(3,20,0) +# include <gdkmm/seat.h> +#endif + using Inkscape::Debug::GdkEventLatencyTracker; // gtk_check_version returns non-NULL on failure @@ -61,6 +66,20 @@ struct SPCanvasGroupClass { SPCanvasItemClass parent_class; }; +static void ungrab_default_client_pointer(guint32 const time = GDK_CURRENT_TIME) +{ + auto const display = Gdk::Display::get_default(); + +#if GTK_CHECK_VERSION(3,20,0) + auto const seat = display->get_default_seat(); + seat->ungrab(); +#else + auto const dm = display->get_device_manager(); + auto const device = dm->get_client_pointer(); + device->ungrab(time); +#endif +} + /** * A group of items. */ @@ -321,14 +340,7 @@ void sp_canvas_item_dispose(GObject *object) if (item == item->canvas->_grabbed_item) { item->canvas->_grabbed_item = NULL; - -#if GTK_CHECK_VERSION(3,0,0) - GdkDeviceManager *dm = gdk_display_get_device_manager(gdk_display_get_default()); - GdkDevice *device = gdk_device_manager_get_client_pointer(dm); - gdk_device_ungrab(device, GDK_CURRENT_TIME); -#else - gdk_pointer_ungrab (GDK_CURRENT_TIME); -#endif + ungrab_default_client_pointer(); } if (item == item->canvas->_focused_item) { @@ -616,10 +628,22 @@ int sp_canvas_item_grab(SPCanvasItem *item, guint event_mask, GdkCursor *cursor, // fixme: Top hack (Lauris) // fixme: If we add key masks to event mask, Gdk will abort (Lauris) - // fixme: But Canvas actualle does get key events, so all we need is routing these here -#if GTK_CHECK_VERSION(3,0,0) - GdkDeviceManager *dm = gdk_display_get_device_manager(gdk_display_get_default()); - GdkDevice *device = gdk_device_manager_get_client_pointer(dm); + // fixme: But Canvas actually does get key events, so all we need is routing these here + auto display = gdk_display_get_default(); +#if GTK_CHECK_VERSION(3,20,0) + auto seat = gdk_display_get_default_seat(display); + gdk_seat_grab(seat, + getWindow(item->canvas), + GDK_SEAT_CAPABILITY_ALL_POINTING, + FALSE, + cursor, + NULL, + NULL, + NULL); +#else + auto dm = gdk_display_get_device_manager(display); + auto device = gdk_device_manager_get_client_pointer(dm); + gdk_device_grab(device, getWindow(item->canvas), GDK_OWNERSHIP_NONE, @@ -627,10 +651,6 @@ int sp_canvas_item_grab(SPCanvasItem *item, guint event_mask, GdkCursor *cursor, (GdkEventMask)(event_mask & (~(GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK))), cursor, etime); -#else - gdk_pointer_grab( getWindow(item->canvas), FALSE, - (GdkEventMask)(event_mask & (~(GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK))), - NULL, cursor, etime); #endif item->canvas->_grabbed_item = item; @@ -657,14 +677,7 @@ void sp_canvas_item_ungrab(SPCanvasItem *item, guint32 etime) } item->canvas->_grabbed_item = NULL; - -#if GTK_CHECK_VERSION(3,0,0) - GdkDeviceManager *dm = gdk_display_get_device_manager(gdk_display_get_default()); - GdkDevice *device = gdk_device_manager_get_client_pointer(dm); - gdk_device_ungrab(device, etime); -#else - gdk_pointer_ungrab (etime); -#endif + ungrab_default_client_pointer(etime); } /** @@ -913,16 +926,9 @@ void sp_canvas_class_init(SPCanvasClass *klass) widget_class->realize = SPCanvas::handle_realize; widget_class->unrealize = SPCanvas::handle_unrealize; - -#if GTK_CHECK_VERSION(3,0,0) widget_class->get_preferred_width = SPCanvas::handle_get_preferred_width; widget_class->get_preferred_height = SPCanvas::handle_get_preferred_height; widget_class->draw = SPCanvas::handle_draw; -#else - widget_class->size_request = SPCanvas::handle_size_request; - widget_class->expose_event = SPCanvas::handle_expose; -#endif - widget_class->size_allocate = SPCanvas::handle_size_allocate; widget_class->button_press_event = SPCanvas::handle_button; widget_class->button_release_event = SPCanvas::handle_button; @@ -980,13 +986,7 @@ void SPCanvas::shutdownTransients() if (_grabbed_item) { _grabbed_item = NULL; -#if GTK_CHECK_VERSION(3,0,0) - GdkDeviceManager *dm = gdk_display_get_device_manager(gdk_display_get_default()); - GdkDevice *device = gdk_device_manager_get_client_pointer(dm); - gdk_device_ungrab(device, GDK_CURRENT_TIME); -#else - gdk_pointer_ungrab(GDK_CURRENT_TIME); -#endif + ungrab_default_client_pointer(); } removeIdle(); } @@ -1051,11 +1051,7 @@ void SPCanvas::handle_realize(GtkWidget *widget) attributes.width = allocation.width; attributes.height = allocation.height; attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gdk_visual_get_system(); - -#if !GTK_CHECK_VERSION(3,0,0) - attributes.colormap = gdk_colormap_get_system(); -#endif + attributes.visual = gdk_screen_get_system_visual(gdk_screen_get_default()); attributes.event_mask = (gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK | @@ -1073,11 +1069,7 @@ void SPCanvas::handle_realize(GtkWidget *widget) GDK_SCROLL_MASK | GDK_FOCUS_CHANGE_MASK); -#if GTK_CHECK_VERSION(3,0,0) gint attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; -#else - gint attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; -#endif GdkWindow *window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); gtk_widget_set_window (widget, window); @@ -1086,18 +1078,8 @@ void SPCanvas::handle_realize(GtkWidget *widget) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (prefs->getBool("/options/useextinput/value", true)) { gtk_widget_set_events(widget, attributes.event_mask); -#if !GTK_CHECK_VERSION(3,0,0) - gtk_widget_set_extension_events(widget, GDK_EXTENSION_EVENTS_ALL); - // TODO: Extension event stuff has been deprecated in GTK+ 3 -#endif } -#if !GTK_CHECK_VERSION(3,0,0) - // This does nothing in GTK+ 3 - GtkStyle *style = gtk_widget_get_style (widget); - gtk_widget_set_style (widget, gtk_style_attach (style, window)); -#endif - gtk_widget_set_realized (widget, TRUE); } @@ -1115,8 +1097,6 @@ void SPCanvas::handle_unrealize(GtkWidget *widget) (* GTK_WIDGET_CLASS(sp_canvas_parent_class)->unrealize)(widget); } - -#if GTK_CHECK_VERSION(3,0,0) void SPCanvas::handle_get_preferred_width(GtkWidget *widget, gint *minimum_width, gint *natural_width) { static_cast<void>(SP_CANVAS (widget)); @@ -1130,16 +1110,6 @@ void SPCanvas::handle_get_preferred_height(GtkWidget *widget, gint *minimum_heig *minimum_height = 256; *natural_height = 256; } -#else -void SPCanvas::handle_size_request(GtkWidget *widget, GtkRequisition *req) -{ - static_cast<void>(SP_CANVAS (widget)); - - req->width = 256; - req->height = 256; -} -#endif - void SPCanvas::handle_size_allocate(GtkWidget *widget, GtkAllocation *allocation) { @@ -1219,9 +1189,7 @@ int SPCanvas::emitEvent(GdkEvent *event) break; case GDK_SCROLL: mask = GDK_SCROLL_MASK; -#if GTK_CHECK_VERSION(3,0,0) mask |= GDK_SMOOTH_SCROLL_MASK; -#endif break; default: mask = 0; @@ -1503,13 +1471,9 @@ gint SPCanvas::handle_scroll(GtkWidget *widget, GdkEventScroll *event) } static inline void request_motions(GdkWindow *w, GdkEventMotion *event) { -#if GTK_CHECK_VERSION(3,0,0) gdk_window_get_device_position(w, gdk_event_get_device((GdkEvent *)(event)), NULL, NULL, NULL); -#else - gdk_window_get_pointer(w, NULL, NULL, NULL); -#endif gdk_event_request_motions(event); } @@ -1543,7 +1507,7 @@ void SPCanvas::paintSingleBuffer(Geom::IntRect const &paint_rect, Geom::IntRect buf.buf = NULL; buf.buf_rowstride = 0; buf.rect = paint_rect; - buf.visible_rect = canvas_rect; + buf.canvas_rect = canvas_rect; buf.is_empty = true; // create temporary surface @@ -1607,7 +1571,7 @@ void SPCanvas::paintSingleBuffer(Geom::IntRect const &paint_rect, Geom::IntRect } struct PaintRectSetup { - Geom::IntRect big_rect; + Geom::IntRect canvas_rect; GTimeVal start_time; int max_pixels; Geom::Point mouse_loc; @@ -1666,7 +1630,7 @@ int SPCanvas::paintRectInternal(PaintRectSetup const *setup, Geom::IntRect const gdk_window_begin_paint_rect(window, &r); */ - paintSingleBuffer(this_rect, setup->big_rect, bw); + paintSingleBuffer(this_rect, setup->canvas_rect, bw); //gdk_window_end_paint(window); return 1; } @@ -1731,6 +1695,7 @@ bool SPCanvas::paintRect(int xx0, int yy0, int xx1, int yy1) gtk_widget_get_allocation(GTK_WIDGET(this), &allocation); + // Find window rectangle in 'world coordinates'. Geom::IntRect canvas_rect = Geom::IntRect::from_xywh(_x0, _y0, allocation.width, allocation.height); Geom::IntRect paint_rect(xx0, yy0, xx1, yy1); @@ -1741,28 +1706,37 @@ bool SPCanvas::paintRect(int xx0, int yy0, int xx1, int yy1) paint_rect = *area; PaintRectSetup setup; - setup.big_rect = paint_rect; + setup.canvas_rect = canvas_rect; // Save the mouse location gint x, y; -#if GTK_CHECK_VERSION(3,0,0) - GdkDeviceManager *dm = gdk_display_get_device_manager(gdk_display_get_default()); - GdkDevice *device = gdk_device_manager_get_client_pointer(dm); + auto const display = Gdk::Display::get_default(); - gdk_window_get_device_position(gtk_widget_get_window(GTK_WIDGET(this)), - device, - &x, &y, NULL); +#if GTK_CHECK_VERSION(3,20,0) + auto const seat = display->get_default_seat(); + auto const device = seat->get_pointer(); #else - gdk_window_get_pointer(gtk_widget_get_window(GTK_WIDGET(this)), &x, &y, NULL); + auto const dm = display->get_device_manager(); + auto const device = dm->get_client_pointer(); #endif + gdk_window_get_device_position(gtk_widget_get_window(GTK_WIDGET(this)), + device->gobj(), + &x, &y, NULL); + setup.mouse_loc = sp_canvas_window_to_world(this, Geom::Point(x,y)); + static unsigned tile_multiplier = 0; + if (tile_multiplier == 0) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + tile_multiplier = prefs->getIntLimited("/options/rendering/tile-multiplier", 1, 1, 64); + } + if (_rendermode != Inkscape::RENDERMODE_OUTLINE) { // use 256K as a compromise to not slow down gradients // 256K is the cached buffer and we need 4 channels - setup.max_pixels = 65536; // 256K/4 + setup.max_pixels = 65536 * tile_multiplier; // 256K/4 } else { // paths only, so 1M works faster // 1M is the cached buffer and we need 4 channels @@ -1818,21 +1792,6 @@ gboolean SPCanvas::handle_draw(GtkWidget *widget, cairo_t *cr) { return TRUE; } -#if !GTK_CHECK_VERSION(3,0,0) -gboolean SPCanvas::handle_expose(GtkWidget *widget, GdkEventExpose *event) -{ - cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); - - gdk_cairo_region (cr, event->region); - cairo_clip (cr); - gboolean result = SPCanvas::handle_draw(widget, cr); - - cairo_destroy (cr); - - return result; -} -#endif - gint SPCanvas::handle_key_event(GtkWidget *widget, GdkEventKey *event) { @@ -1965,10 +1924,16 @@ SPCanvasGroup *SPCanvas::getRoot() return SP_CANVAS_GROUP(_root); } -void SPCanvas::scrollTo(double cx, double cy, unsigned int clear, bool is_scrolling) +/** + * Scroll screen to point 'c'. 'c' is measured in screen pixels. + */ +void SPCanvas::scrollTo( Geom::Point const &c, unsigned int clear, bool is_scrolling) { GtkAllocation allocation; + double cx = c[Geom::X]; + double cy = c[Geom::Y]; + int ix = (int) round(cx); // ix and iy are the new canvas coordinates (integer screen pixels) int iy = (int) round(cy); // cx might be negative, so (int)(cx + 0.5) will not do! int dx = ix - _x0; // dx and dy specify the displacement (scroll) of the @@ -1989,6 +1954,7 @@ void SPCanvas::scrollTo(double cx, double cy, unsigned int clear, bool is_scroll cairo_translate(cr, -ix, -iy); cairo_set_source(cr, _background); cairo_paint(cr); + // Copy the old backing store contents cairo_set_source_surface(cr, _backing_store, _x0, _y0); cairo_rectangle(cr, _x0, _y0, allocation.width, allocation.height); |
