diff --git a/share/keys/inkscape.xml b/share/keys/inkscape.xml index a2f63dc43e69a49be84a693c13c1fc28298a65f3..7e0e3b4a3f98bec132bab794b604f768b2bf122e 100644 --- a/share/keys/inkscape.xml +++ b/share/keys/inkscape.xml @@ -29,22 +29,22 @@ override) the bindings in the main default.xml. - - + + - + - + - + - + diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index 65e473a2ba8312a671f7fd4675bff0efeccc4dc5..7fb179777320fb41e42fce8f0ff53ae83a85b155 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -1341,11 +1341,14 @@ void CairoRenderContext::_setFillStyle(SPStyle const *const style, Geom::OptRect { g_return_if_fail( !style->fill.set || style->fill.isColor() + || style->fill.isContext() || style->fill.isPaintserver() ); float const alpha = _mergedOpacity(SP_SCALE24_TO_FLOAT(style->fill_opacity.value)); SPPaintServer const *paint_server = style->getFillPaintServer(); - if (paint_server && paint_server->isValid()) { + if (style->fill.isContext()) { + // Do nothing. These are valid values but if not inside a or element do nothing. + } else if (paint_server && paint_server->isValid()) { g_assert(is(SP_STYLE_FILL_SERVER(style)) || is(SP_STYLE_FILL_SERVER(style)) @@ -1368,7 +1371,9 @@ void CairoRenderContext::_setFillStyle(SPStyle const *const style, Geom::OptRect void CairoRenderContext::_setStrokeStyle(SPStyle const *style, Geom::OptRect const &pbox) { float const alpha = _mergedOpacity(SP_SCALE24_TO_FLOAT(style->stroke_opacity.value)); - if (style->stroke.isColor() || (style->stroke.isPaintserver() && !style->getStrokePaintServer()->isValid())) { + if (style->stroke.isContext()) { + // Do nothing. These are valid values but if not inside a or element do nothing. + } else if (style->stroke.isColor() || (style->stroke.isPaintserver() && !style->getStrokePaintServer()->isValid())) { ink_cairo_set_source_color(_cr, style->stroke.getColor(), alpha); } else { g_assert( style->stroke.isPaintserver() @@ -1524,10 +1529,17 @@ bool CairoRenderContext::renderPathVector(Geom::PathVector const &pathv, return true; } - bool no_fill = style->fill.isNone() || style->fill_opacity.value == 0 || + bool no_fill = + style->fill.isNone() || + style->fill.isContext() || + style->fill_opacity.value == 0 || order == STROKE_ONLY; - bool no_stroke = style->stroke.isNone() || (!style->stroke_extensions.hairline && style->stroke_width.computed < 1e-9) || - style->stroke_opacity.value == 0 || order == FILL_ONLY; + bool no_stroke = + style->stroke.isNone() || + style->stroke.isContext() || + (!style->stroke_extensions.hairline && style->stroke_width.computed < 1e-9) || + style->stroke_opacity.value == 0 || + order == FILL_ONLY; if (no_fill && no_stroke) return true; diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index 073cd1c981462ccfe87d18e9c8dbb89ea77145e0..4bbae3806ea15176d93c1a8e293c501bb0c6c9e3 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -179,16 +179,16 @@ public: { auto const fill_origin = target_style->fill.paintOrigin; if (fill_origin == SP_CSS_PAINT_ORIGIN_CONTEXT_FILL) { - _copyPaint(&target_style->fill, _findContextPaint(true)); + _copyPaint(&target_style->fill, *_origin->style->getFillOrStroke(true)); } else if (fill_origin == SP_CSS_PAINT_ORIGIN_CONTEXT_STROKE) { - _copyPaint(&target_style->fill, _findContextPaint(false)); + _copyPaint(&target_style->fill, *_origin->style->getFillOrStroke(false)); } auto const stroke_origin = target_style->stroke.paintOrigin; if (stroke_origin == SP_CSS_PAINT_ORIGIN_CONTEXT_FILL) { - _copyPaint(&target_style->stroke, _findContextPaint(true)); + _copyPaint(&target_style->stroke, *_origin->style->getFillOrStroke(true)); } else if (stroke_origin == SP_CSS_PAINT_ORIGIN_CONTEXT_STROKE) { - _copyPaint(&target_style->stroke, _findContextPaint(false)); + _copyPaint(&target_style->stroke, *_origin->style->getFillOrStroke(false)); } } @@ -204,24 +204,6 @@ public: } private: - /** @brief Find the paint that context-fill or context-stroke is referring to. - * - * @param is_fill If true, handle context-fill, otherwise context-stroke. - * @return The paint relevant to the specified context. - */ - SPIPaint _findContextPaint(bool is_fill) const - { - if (auto *clone = cast(_origin); clone && clone->child) { - // Copy the paint of the child and merge with the parent's. This is similar - // to style merge operations performed when unlinking a clone, but here it's - // done only for a paint. - SPIPaint paint = *clone->child->style->getFillOrStroke(is_fill); - paint.merge(clone->style->getFillOrStroke(is_fill)); - return paint; - } - return *_origin->style->getFillOrStroke(is_fill); - } - /** Copy paint from origin to destination, saving a copy of the old paint. */ template void _copyPaint(PainT *destination, SPIPaint paint) @@ -265,17 +247,7 @@ static void sp_shape_render(SPShape const *shape, CairoRenderContext *ctx, SPIte std::unique_ptr context_fs_manager; if (origin) { - // If the shape is a child of a marker, we must set styles from the origin. - auto parentobj = shape->parent; - while (parentobj) { - if (is(parentobj)) { - // Create a manager to temporarily rewrite any fill/stroke properties - // set to context-fill/context-stroke with usable values. - context_fs_manager = std::make_unique(style, origin); - break; - } - parentobj = parentobj->parent; - } + context_fs_manager = std::make_unique(style, origin); } if (style->paint_order.layer[0] == SP_CSS_PAINT_ORDER_NORMAL || @@ -295,12 +267,13 @@ static void sp_shape_render(SPShape const *shape, CairoRenderContext *ctx, SPIte // Render markers bool has_stroke = style->stroke_width.computed > 0.f; - if (shape && shape->hasMarkers() && has_stroke) { + if (shape->hasMarkers() && has_stroke) { for (auto const &[_, marker, tr] : shape->get_markers()) { if (auto marker_item = sp_item_first_item_child(marker)) { auto const old_tr = marker_item->transform; marker_item->transform = old_tr * marker->c2p * tr; - ctx->getRenderer()->renderItem(ctx, marker_item, origin ? origin : shape); + // Marker's context-fill/context-stroke always refer to shape. + ctx->getRenderer()->renderItem(ctx, marker_item, shape); marker_item->transform = old_tr; } } diff --git a/src/object/sp-shape.cpp b/src/object/sp-shape.cpp index 09c9f37878c897390a7df11422fca9d60147fa23..a166b745ef5e446d5a2e6fee6973905c2005d692 100644 --- a/src/object/sp-shape.cpp +++ b/src/object/sp-shape.cpp @@ -686,7 +686,7 @@ void SPShape::update_patheffect(bool write) } Inkscape::DrawingItem* SPShape::show(Inkscape::Drawing &drawing, unsigned int /*key*/, unsigned int /*flags*/) { - // std::cout << "SPShape::set_visible(true): " << (getId()?getId():"null") << std::endl; + // std::cout << "SPShape::show(): " << (getId()?getId():"null") << std::endl; Inkscape::DrawingShape *s = new Inkscape::DrawingShape(drawing); bool has_markers = this->hasMarkers(); diff --git a/src/style-internal.cpp b/src/style-internal.cpp index 3af6d08b118d795a70e479e0ff08b6ab5bc1a3ef..eed7d1a35af1fc442402f7995574d4124c240de9 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -1700,6 +1700,7 @@ SPIPaint::read( gchar const *str ) { if (streq(str, "currentColor")) { set = true; paintOrigin = SP_CSS_PAINT_ORIGIN_CURRENT_COLOR; + paintSource = paintOrigin; if (style) { setColor(style->color.getColor()); } else { @@ -1713,9 +1714,11 @@ SPIPaint::read( gchar const *str ) { } else if (streq(str, "context-fill")) { set = true; paintOrigin = SP_CSS_PAINT_ORIGIN_CONTEXT_FILL; + paintSource = paintOrigin; } else if (streq(str, "context-stroke")) { set = true; paintOrigin = SP_CSS_PAINT_ORIGIN_CONTEXT_STROKE; + paintSource = paintOrigin; } else if (streq(str, "none")) { set = true; noneSet = true; @@ -1735,7 +1738,7 @@ const Glib::ustring SPIPaint::get_value() const if (this->href && this->href->getURI()) { ret += this->href->getURI()->cssStr(); } - switch(this->paintOrigin) { + switch(this->paintSource) { case SP_CSS_PAINT_ORIGIN_CURRENT_COLOR: if (!ret.empty()) ret += " "; ret += "currentColor"; @@ -1784,6 +1787,7 @@ SPIPaint::reset( bool init ) { // std::cout << "SPIPaint::reset(): " << name << " " << init << std::endl; SPIBase::clear(); paintOrigin = SP_CSS_PAINT_ORIGIN_NORMAL; + paintSource = paintOrigin; noneSet = false; _color.reset(); tag = nullptr; @@ -1817,6 +1821,8 @@ SPIPaint::cascade( const SPIBase* const parent ) { } else if( p->paintOrigin == SP_CSS_PAINT_ORIGIN_CURRENT_COLOR ) { paintOrigin = SP_CSS_PAINT_ORIGIN_CURRENT_COLOR; _color = style->color.getColor(); + } else if( p->paintOrigin != SP_CSS_PAINT_ORIGIN_NORMAL ) { + paintOrigin = p->paintOrigin; // context fill/stroke } else if( isNone() ) { // } else { @@ -1854,7 +1860,8 @@ SPIPaint::equals(const SPIBase& rhs) const { if ( (this->isColor() != r->isColor() ) || (this->isPaintserver() != r->isPaintserver() ) || - (this->paintOrigin != r->paintOrigin ) ) { + (this->paintOrigin != r->paintOrigin ) || + (this->paintSource != r->paintSource )) { return false; } diff --git a/src/style-internal.h b/src/style-internal.h index ff3972009dc4e3cbe72c8320c053c6834553cfb9..b5c78b29ef30ab58d4b3a10a26a479fe0e548b4a 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -737,6 +737,7 @@ public: SPIPaint& operator=(const SPIPaint& rhs) { SPIBase::operator=(rhs); paintOrigin = rhs.paintOrigin; + paintSource = rhs.paintSource; noneSet = rhs.noneSet; _color = rhs._color; href = rhs.href; @@ -746,7 +747,11 @@ public: bool equals(const SPIBase& rhs) const override; bool isSameType( SPIPaint const & other ) const { - return (isPaintserver() == other.isPaintserver()) && (isColor() == other.isColor()) && (paintOrigin == other.paintOrigin); + return + (isPaintserver() == other.isPaintserver()) && + (isColor() == other.isColor()) && + (paintOrigin == other.paintOrigin) && + (paintSource == other.paintSource); } bool isNoneSet() const { @@ -765,6 +770,12 @@ public: return href && href->getObject() != nullptr; } + bool isContext() const { + return + paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_FILL || + paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_STROKE; + } + void setNone() { noneSet = true; _color.reset(); @@ -780,7 +791,8 @@ public: Colors::DocumentCMS const &getCMS() const; // To do: make private public: - SPPaintOrigin paintOrigin : 2; + SPPaintOrigin paintOrigin : 2; // Inherited value (from cascade) + SPPaintOrigin paintSource: 2; // Set value (from XML) bool noneSet : 1; std::shared_ptr href; SPObject *tag = nullptr; diff --git a/src/ui/modifiers.cpp b/src/ui/modifiers.cpp index c958b10854417a2b974e0981104907ab8acd75d3..53b90824672f222ee3ccb7d2b8ff025292850d22 100644 --- a/src/ui/modifiers.cpp +++ b/src/ui/modifiers.cpp @@ -254,8 +254,12 @@ std::string generate_label(KeyMask mask, std::string sep) ret.append(_("Hyper")); } if(mask & META) { + #ifdef __APPLE__ + ret.append(_("Command")); + #else if(!ret.empty()) ret.append(sep); ret.append(_("Meta")); + #endif } return ret; } @@ -285,10 +289,15 @@ unsigned long calculate_weight(KeyMask mask) */ void responsive_tooltip(MessageContext *message_context, KeyEvent const &event, int num_args, ...) { + #ifdef __APPLE__ + std::string alt_msg = "Option: "; + #else + std::string alt_msg = "Alt: "; + #endif + std::string meta_msg = "Command: "; std::string ctrl_msg = "Ctrl: "; std::string shift_msg = "Shift: "; - std::string alt_msg = "Alt: "; - + bool meta_case = false; // NOTE: This will hide any keys changed to SUPER or multiple keys such as CTRL+SHIFT va_list args; va_start(args, num_args); @@ -296,6 +305,10 @@ void responsive_tooltip(MessageContext *message_context, KeyEvent const &event, auto modifier = Modifier::get(va_arg(args, Type)); auto name = std::string(_(modifier->get_name())); switch (modifier->get_and_mask()) { + case META: + meta_msg += name + ", "; + meta_case = true; + break; case CTRL: ctrl_msg += name + ", "; break; @@ -313,9 +326,10 @@ void responsive_tooltip(MessageContext *message_context, KeyEvent const &event, ctrl_msg.erase(ctrl_msg.size() - 2); shift_msg.erase(shift_msg.size() - 2); alt_msg.erase(alt_msg.size() - 2); - + if(meta_case) + meta_msg.erase(meta_msg.size() - 2); UI::Tools::sp_event_show_modifier_tip(message_context, event, - ctrl_msg.c_str(), shift_msg.c_str(), alt_msg.c_str()); + ctrl_msg.c_str(), shift_msg.c_str(), alt_msg.c_str(),(meta_case? meta_msg.c_str():nullptr)); } /** diff --git a/src/ui/tools/arc-tool.cpp b/src/ui/tools/arc-tool.cpp index 8f221914cb5e08ca919652848d0e1625bf2865c8..7e8e2e74fda1e7346cdfdf1edb39aa58effa6140 100644 --- a/src/ui/tools/arc-tool.cpp +++ b/src/ui/tools/arc-tool.cpp @@ -42,6 +42,7 @@ #include "ui/widget/events/canvas-event.h" #include "util/units.h" +#include "src/ui/util.h" using Inkscape::DocumentUndo; @@ -383,7 +384,8 @@ void ArcTool::drag(Geom::Point const &pt, unsigned state) } } } else { - this->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Ellipse: %s × %s; with Ctrl to make circle, integer-ratio, or golden-ratio ellipse; with Shift to draw around the starting point"), xs.c_str(), ys.c_str()); + std::string ctrl_command=get_ctrl_or_command(); + this->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Ellipse: %s × %s; with %s to make circle, integer-ratio, or golden-ratio ellipse; with Shift to draw around the starting point"), xs.c_str(), ys.c_str(),ctrl_command.c_str()); } } diff --git a/src/ui/tools/gradient-tool.cpp b/src/ui/tools/gradient-tool.cpp index cbcdf8e39719b61c8749bf4ef00f5e337127547e..c2ce265029cb26c2681b344313a84f765e719399 100644 --- a/src/ui/tools/gradient-tool.cpp +++ b/src/ui/tools/gradient-tool.cpp @@ -36,6 +36,8 @@ #include "ui/icon-names.h" #include "ui/tools/gradient-tool.h" #include "ui/widget/events/canvas-event.h" +#include "src/ui/util.h" + using Inkscape::DocumentUndo; @@ -764,10 +766,11 @@ void GradientTool::drag(Geom::Point const &pt, uint32_t etime) // status text; we do not track coords because this branch is run once, not all the time // during drag int const n_objects = boost::distance(selection->items()); + std::string ctrl_command=get_ctrl_or_command(); message_context->setF(NORMAL_MESSAGE, - ngettext("Gradient for %d object; with Ctrl to snap angle", - "Gradient for %d objects; with Ctrl to snap angle", n_objects), - n_objects); + ngettext("Gradient for %d object; with %s to snap angle", + "Gradient for %d objects; with %s to snap angle", n_objects), + n_objects,ctrl_command.c_str()); } else { _desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select objects on which to create gradient.")); } diff --git a/src/ui/tools/mesh-tool.cpp b/src/ui/tools/mesh-tool.cpp index 3162c33b2d573afec4de868351b73d9096ed0677..0a29e2c173c953e83c232d958916e58f1ffa60d3 100644 --- a/src/ui/tools/mesh-tool.cpp +++ b/src/ui/tools/mesh-tool.cpp @@ -47,6 +47,8 @@ #include "ui/icon-names.h" #include "ui/widget/events/canvas-event.h" +#include "src/ui/util.h" + using Inkscape::DocumentUndo; namespace Inkscape { @@ -887,10 +889,11 @@ void MeshTool::new_default() // status text; we do not track coords because this branch is run once, not all the time // during drag int n_objects = (int) boost::distance(selection->items()); + std::string ctrl_command= get_ctrl_or_command(); message_context->setF(Inkscape::NORMAL_MESSAGE, - ngettext("Gradient for %d object; with Ctrl to snap angle", - "Gradient for %d objects; with Ctrl to snap angle", n_objects), - n_objects); + ngettext("Gradient for %d object; with %s to snap angle", + "Gradient for %d objects; with %s to snap angle", n_objects), + n_objects,ctrl_command.c_str()); } else { _desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select objects on which to create gradient.")); } diff --git a/src/ui/tools/rect-tool.cpp b/src/ui/tools/rect-tool.cpp index 12916edfce348ad5ccc5459101858c0a2aee6b49..b61b5d0913989ea1f3bdf7a52b81cee3111c85a4 100644 --- a/src/ui/tools/rect-tool.cpp +++ b/src/ui/tools/rect-tool.cpp @@ -39,6 +39,8 @@ #include "ui/widget/events/canvas-event.h" #include "util/units.h" +#include "src/ui/util.h" + using Inkscape::DocumentUndo; @@ -379,9 +381,10 @@ void RectTool::drag(Geom::Point const pt, unsigned state) { } } } else { + std::string ctrl_command=get_ctrl_or_command(); this->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, - _("Rectangle: %s × %s; with Ctrl to make square, integer-ratio, or golden-ratio rectangle; with Shift to draw around the starting point"), - xs.c_str(), ys.c_str()); + _("Rectangle: %s × %s; with %s to make square, integer-ratio, or golden-ratio rectangle; with Shift to draw around the starting point"), + xs.c_str(), ys.c_str(),ctrl_command.c_str()); } } diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index 7c927aaba75426c8970e25d3400457f9f935ff36..cbf0c8f63f6bb3d652ed0f51c1749056cafc3299 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -1262,20 +1262,29 @@ void ToolBase::menu_popup(CanvasEvent const &event, SPObject *obj) */ void sp_event_show_modifier_tip(MessageContext *message_context, KeyEvent const &event, char const *ctrl_tip, char const *shift_tip, - char const *alt_tip) + char const *alt_tip,char const *meta_tip) { auto const keyval = get_latin_keyval(event); - - bool ctrl = ctrl_tip && (mod_ctrl(event) || keyval == GDK_KEY_Control_L || keyval == GDK_KEY_Control_R); - bool shift = shift_tip && (mod_shift(event) || keyval == GDK_KEY_Shift_L || keyval == GDK_KEY_Shift_R); - bool alt = alt_tip && (mod_alt(event) || keyval == GDK_KEY_Alt_L || keyval == GDK_KEY_Alt_R - || keyval == GDK_KEY_Meta_L || keyval == GDK_KEY_Meta_R); - - char *tip = g_strdup_printf("%s%s%s%s%s", ctrl ? ctrl_tip : "", + bool meta = false; + bool ctrl = ctrl_tip && (mod_ctrl(event) || keyval == GDK_KEY_Control_L || keyval == GDK_KEY_Control_R); + bool shift = shift_tip && (mod_shift(event) || keyval == GDK_KEY_Shift_L || keyval == GDK_KEY_Shift_R); + bool alt = alt_tip && (mod_alt(event) || keyval == GDK_KEY_Alt_L || keyval == GDK_KEY_Alt_R); + if(meta_tip){ + meta = meta_tip && (mod_meta(event) || keyval == GDK_KEY_Meta_L || keyval == GDK_KEY_Meta_R); + } + else{ + alt = alt || keyval == GDK_KEY_Meta_L || keyval == GDK_KEY_Meta_R; + } + + char *tip = g_strdup_printf("%s%s%s%s%s%s%s%s", ctrl ? ctrl_tip : "", ctrl && (shift || alt) ? "; " : "", shift ? shift_tip : "", (ctrl || shift) && alt ? "; " : "", - alt ? alt_tip : ""); + alt ? alt_tip : "", + meta ? meta_tip: "", + meta && (shift || alt) ? "; " : "", + (meta || shift) && alt ? "; " : "" + ); if (std::strlen(tip) > 0) { message_context->flash(INFORMATION_MESSAGE, tip); diff --git a/src/ui/tools/tool-base.h b/src/ui/tools/tool-base.h index b79c414a6d9d1fe25bbad02e368bf4554010cd39..04b6596fbebf727fce2a31e2de7df5b786588054 100644 --- a/src/ui/tools/tool-base.h +++ b/src/ui/tools/tool-base.h @@ -244,7 +244,7 @@ inline int gobble_key_events(unsigned keyval, unsigned mask) { return 0; } inline void gobble_motion_events(unsigned mask) {} void sp_event_show_modifier_tip(MessageContext *message_context, KeyEvent const &event, - char const *ctrl_tip, char const *shift_tip, char const *alt_tip); + char const *ctrl_tip, char const *shift_tip, char const *alt_tip,char const *meta_tip = nullptr); void init_latin_keys_group(); // Prefer one of the non-_impl versions below. This is public for shortcuts.cpp. diff --git a/src/ui/util.cpp b/src/ui/util.cpp index ce71ebc2c508dc4fdbac731626ac332639e91331..13306b04e58b6a8b7ba2e774a478ed082f29e9ba 100644 --- a/src/ui/util.cpp +++ b/src/ui/util.cpp @@ -550,6 +550,14 @@ char const *get_text(Gtk::Editable const &editable) return gtk_editable_get_text(const_cast(editable.gobj())); // C API is const-incorrect } +char const* get_ctrl_or_command() +{ + #ifdef __APPLE__ + return "Command"; + #else + return "Ctrl"; + #endif +} /* Local Variables: mode:c++ diff --git a/src/ui/util.h b/src/ui/util.h index 3f21e96d17f9d2c38f96b5527dc02cb29715b6bb..0a3796f70f4cbb314b3463cbaf7bf6f31cd76504 100644 --- a/src/ui/util.h +++ b/src/ui/util.h @@ -246,6 +246,7 @@ void restrict_minsize_to_square(Gtk::Widget& widget, int min_size_px); /// Get the text from a GtkEditable without the temporary copy imposed by gtkmm. char const *get_text(Gtk::Editable const &editable); +char const* get_ctrl_or_command(); #endif // UI_UTIL_SEEN diff --git a/src/ui/widget/events/canvas-event.h b/src/ui/widget/events/canvas-event.h index a53a0c11eb8903295ee7cc83a9b1a142da5be35d..fd5bcde7a165ca0fa32c8ea097487eafa0ac9f60 100644 --- a/src/ui/widget/events/canvas-event.h +++ b/src/ui/widget/events/canvas-event.h @@ -332,16 +332,20 @@ inline constexpr auto INK_GDK_MODIFIER_MASK = GDK_SHIFT_MASK | GDK_CONTROL_MASK inline bool mod_shift(unsigned modifiers) { return modifiers & GDK_SHIFT_MASK; } inline bool mod_ctrl(unsigned modifiers) { return modifiers & GDK_CONTROL_MASK; } +inline bool mod_meta(unsigned modifiers) { return modifiers & GDK_META_MASK; } inline bool mod_alt(unsigned modifiers) { return modifiers & GDK_ALT_MASK; } inline bool mod_shift_only(unsigned modifiers) { return (modifiers & INK_GDK_MODIFIER_MASK) == GDK_SHIFT_MASK; } inline bool mod_ctrl_only(unsigned modifiers) { return (modifiers & INK_GDK_MODIFIER_MASK) == GDK_CONTROL_MASK; } +inline bool mod_meta_only(unsigned modifiers) { return (modifiers & INK_GDK_MODIFIER_MASK) == GDK_META_MASK; } inline bool mod_alt_only(unsigned modifiers) { return (modifiers & INK_GDK_MODIFIER_MASK) == GDK_ALT_MASK; } inline bool mod_shift(KeyEvent const &event) { return mod_shift(event.modifiers); } inline bool mod_ctrl(KeyEvent const &event) { return mod_ctrl(event.modifiers); } +inline bool mod_meta(KeyEvent const &event) { return mod_meta(event.modifiers); } inline bool mod_alt(KeyEvent const &event) { return mod_alt(event.modifiers); } inline bool mod_shift_only(KeyEvent const &event) { return mod_shift_only(event.modifiers); } inline bool mod_ctrl_only(KeyEvent const &event) { return mod_ctrl_only(event.modifiers); } +inline bool mod_meta_only(KeyEvent const &event) { return mod_meta_only(event.modifiers); } inline bool mod_alt_only(KeyEvent const &event) { return mod_alt_only(event.modifiers); } /* @@ -351,9 +355,11 @@ inline bool mod_alt_only(KeyEvent const &event) { return mod_alt_only(event.modi inline bool state_held_shift(unsigned state) { return state & GDK_SHIFT_MASK; } inline bool state_held_ctrl(unsigned state) { return state & GDK_CONTROL_MASK; } +inline bool state_held_meta(unsigned state) { return state & GDK_META_MASK; } inline bool state_held_alt(unsigned state) { return state & GDK_ALT_MASK; } inline bool state_held_only_shift(unsigned state) { return (state & INK_GDK_MODIFIER_MASK) == GDK_SHIFT_MASK; } inline bool state_held_only_ctrl(unsigned state) { return (state & INK_GDK_MODIFIER_MASK) == GDK_CONTROL_MASK; } +inline bool state_held_only_meta(unsigned state) { return (state & INK_GDK_MODIFIER_MASK) == GDK_META_MASK; } inline bool state_held_only_alt(unsigned state) { return (state & INK_GDK_MODIFIER_MASK) == GDK_ALT_MASK; } inline bool state_held_any_modifiers(unsigned state) { return state & INK_GDK_MODIFIER_MASK; } inline bool state_held_no_modifiers(unsigned state) { return !state_held_any_modifiers(state); } @@ -363,9 +369,11 @@ inline bool state_held_button(unsigned state) { return (1 <= button || button <= inline bool held_shift(CanvasEvent const &event) { return state_held_shift(event.modifiers); } inline bool held_ctrl(CanvasEvent const &event) { return state_held_ctrl(event.modifiers); } +inline bool held_meta(CanvasEvent const &event) { return state_held_meta(event.modifiers); } inline bool held_alt(CanvasEvent const &event) { return state_held_alt(event.modifiers); } inline bool held_only_shift(CanvasEvent const &event) { return state_held_only_shift(event.modifiers); } inline bool held_only_ctrl(CanvasEvent const &event) { return state_held_only_ctrl(event.modifiers); } +inline bool held_only_meta(CanvasEvent const &event) { return state_held_only_meta(event.modifiers); } inline bool held_only_alt(CanvasEvent const &event) { return state_held_only_alt(event.modifiers); } inline bool held_any_modifiers(CanvasEvent const &event) { return state_held_any_modifiers(event.modifiers); } inline bool held_no_modifiers(CanvasEvent const &event) { return state_held_no_modifiers(event.modifiers); } diff --git a/testfiles/cli_tests/testcases/pdfoutput/expected/08-clones-1.png b/testfiles/cli_tests/testcases/pdfoutput/expected/08-clones-1.png index c930900518082118cba2fc8e0eb5f45c7498077c..68f63ff911298e09aefad1f931a76f2a40e02370 100644 Binary files a/testfiles/cli_tests/testcases/pdfoutput/expected/08-clones-1.png and b/testfiles/cli_tests/testcases/pdfoutput/expected/08-clones-1.png differ