Class for interaction with windows
Methods
Public Class
Public Instance
Public Instance Aliases
click | -> | send_button |
Aliases |
Public Class methods
subextWindowInit {{{
Initialize Window object.
win = Subtlext::Window.new(:x => 5, :y => 5) do |w| s.background = "#ffffff" end
VALUE subextWindowInit(VALUE self, VALUE value) { SubtlextWindow *w = NULL; Data_Get_Struct(self, SubtlextWindow, w); if(w) { VALUE geometry = Qnil; subextSubtlextConnect(NULL); ///< Implicit open connection /* Check object type */ switch(rb_type(value)) { case T_HASH: case T_ARRAY: { XSetWindowAttributes sattrs; XRectangle r = { 0 }; /* Create geometry */ geometry = subextGeometryInstantiate(0, 0, 1, 1); geometry = subextGeometryInit(1, &value, geometry); subextGeometryToRect(geometry, &r); /* Create window */ sattrs.override_redirect = True; w->win = XCreateWindow(display, DefaultRootWindow(display), r.x, r.y, r.width, r.height, 1, CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &sattrs); } break; case T_FIXNUM: case T_BIGNUM: { int x = 0, y = 0; unsigned int width = 0, height = 0, bw = 0, depth = 0; Window root = None; /* Update values */ w->win = FIX2LONG(value); w->flags |= WINDOW_FOREIGN_WIN; /* Get window geometry */ if(XGetGeometry(display, w->win, &root, &x, &y, &width, &height, &bw, &depth)) geometry = subextGeometryInstantiate(x, y, width, height); else rb_raise(rb_eArgError, "Invalid window `%#lx'", w->win); } break; default: rb_raise(rb_eArgError, "Unexpected value-type `%s'", rb_obj_classname(value)); } /* Store data */ rb_iv_set(w->instance, "@win", LONG2NUM(w->win)); rb_iv_set(w->instance, "@geometry", geometry); rb_iv_set(w->instance, "@hidden", Qtrue); /* Set window font */ if(!w->font && !(w->font = subSharedFontNew(display, DEFFONT))) rb_raise(rb_eStandardError, "Invalid font `%s'", DEFFONT); /* Yield to block if given */ if(rb_block_given_p()) rb_yield_values(1, w->instance); XSync(display, False); ///< Sync with X } return Qnil; }
Show window once as long as proc runs
Subtlext::Window.once(:x => 10, :y => 10, :widht => 100, :height => 100) do |w| "test" end => "test"
VALUE subextWindowSingOnce(VALUE self, VALUE geometry) { VALUE win = Qnil, ret = Qnil; rb_need_block(); /* Create new window */ win = subextWindowInstantiate(geometry); /* Yield block */ ret = rb_yield_values(1, win); subextWindowKill(win); return ret; }
Public Instance methods
Whether both objects have the same value. Returns -1, 0 or 1 when self is less than, equal to or grater than other. (based on win)
object1 <=> object2 => 0
static VALUE SubtlextEqualSpaceWindow(VALUE self, VALUE other) { return SubtlextSpaceship(self, other, "@win"); }
Whether both objects have the same values (based on win)
object1 == object2 => true
static VALUE SubtlextEqualWindow(VALUE self, VALUE other) { return SubtlextEqual(self, other, "@win", False); }
Get arbitrary persistent property string or symbol value
object["wm"] => "subtle" object[:wm] => "subtle"
static VALUE SubtlextPropReader(VALUE self, VALUE key) { char *prop = NULL; VALUE ret = Qnil; /* Check ruby object */ rb_check_frozen(self); /* Check object type */ switch(rb_type(key)) { case T_STRING: prop = RSTRING_PTR(key); break; case T_SYMBOL: prop = (char *)SYM2CHAR(key); break; default: rb_raise(rb_eArgError, "Unexpected key value type `%s'", rb_obj_classname(key)); return Qnil; } /* Check results */ if(prop) { char propname[255] = { 0 }, *name = NULL, *result = NULL; Window win = ROOT; VALUE val = Qnil; /* Sanitize property name */ name = strdup(prop); SubtlextStringify(name); /* Check object type */ if(rb_obj_is_instance_of(self, rb_const_get(mod, rb_intern("View")))) { GET_ATTR(self, "@name", val); snprintf(propname, sizeof(propname), "SUBTLE_PROPERTY_%s_%s", RSTRING_PTR(val), name); } else ///< Client { GET_ATTR(self, "@win", val); win = NUM2LONG(val); snprintf(propname, sizeof(propname), "SUBTLE_PROPERTY_%s", name); } /* Get actual property */ if((result = subSharedPropertyGet(display, win, XInternAtom(display, "UTF8_STRING", False), XInternAtom(display, propname, False), NULL))) { ret = rb_str_new2(result); free(result); } free(name); } return ret; }
Set arbitrary persistent property string or symbol value
Symbols are implictly converted to string, to remove a property just set it
to nil
.
object["wm"] = "subtle" => nil object[:wm] = "subtle" => nil object[:wm] = nil => nil
static VALUE SubtlextPropWriter(VALUE self, VALUE key, VALUE value) { VALUE val = Qnil, str = value; char *prop = NULL, *name = NULL, propname[255] = { 0 }; Window win = ROOT; /* Check ruby object */ rb_check_frozen(self); /* Check object type */ switch(rb_type(key)) { case T_STRING: prop = RSTRING_PTR(key); break; case T_SYMBOL: prop = (char *)SYM2CHAR(key); break; default: rb_raise(rb_eArgError, "Unexpected key value-type `%s'", rb_obj_classname(key)); return Qnil; } /* Sanitize property name */ name = strdup(prop); SubtlextStringify(name); /* Assemble property name */ if(rb_obj_is_instance_of(self, rb_const_get(mod, rb_intern("View")))) { GET_ATTR(self, "@name", val); snprintf(propname, sizeof(propname), "SUBTLE_PROPERTY_%s_%s", RSTRING_PTR(val), name); } else ///< Client { GET_ATTR(self, "@win", val); win = NUM2LONG(val); snprintf(propname, sizeof(propname), "SUBTLE_PROPERTY_%s", name); } /* Check value type */ switch(rb_type(value)) { case T_SYMBOL: str = rb_sym_to_s(value); case T_STRING: XChangeProperty(display, win, XInternAtom(display, propname, False), XInternAtom(display, "UTF8_STRING", False), 8, PropModeReplace, (unsigned char *)RSTRING_PTR(str), RSTRING_LEN(str)); break; case T_NIL: XDeleteProperty(display, win, XInternAtom(display, propname, False)); break; default: rb_raise(rb_eArgError, "Unexpected value value-type `%s'", rb_obj_classname(value)); } XSync(display, False); ///< Sync all changes if(name) free(name); return Qnil; }
Set the background color of this Window which can be of following types:
String |
Any color representation of Xlib is allowed |
Array |
Must be an array with values for red, green and blue |
Hash |
Must be a hash with values for red, green and blue |
Fixnum |
Pixel representation of a color in Xlib |
Object |
Copy color from a Color object |
win.background = "#000000" => "#000000"
VALUE subextWindowBackgroundWriter(VALUE self, VALUE value) { SubtlextWindow *w = NULL; /* Check ruby object */ rb_check_frozen(self); Data_Get_Struct(self, SubtlextWindow, w); if(w) { w->bg = subextColorPixel(value, Qnil, Qnil, NULL); XSetWindowBackground(display, w->win, w->bg); } return value; }
Set the border color of this Window which can be of following types:
String |
Any color representation of Xlib is allowed |
Array |
Must be an array with values for red, green and blue |
Hash |
Must be a hash with values for red, green and blue |
Fixnum |
Pixel representation of a color in Xlib |
Object |
Copy color from a Color object |
win.border_color = "#000000" => "#000000"
VALUE subextWindowBorderColorWriter(VALUE self, VALUE value) { SubtlextWindow *w = NULL; /* Check ruby object */ rb_check_frozen(self); Data_Get_Struct(self, SubtlextWindow, w); if(w) { XSetWindowBorder(display, w->win, subextColorPixel(value, Qnil, Qnil, NULL)); XFlush(display); } return Qnil; }
Set border size of this Window.
win.border_size = 3 => 3
VALUE subextWindowBorderSizeWriter(VALUE self, VALUE value) { SubtlextWindow *w = NULL; /* Check ruby object */ rb_check_frozen(self); Data_Get_Struct(self, SubtlextWindow, w); if(w) { int width = 3; /* Check object type */ if(FIXNUM_P(value)) { width = FIX2INT(value); XSetWindowBorderWidth(display, w->win, width); XFlush(display); } else rb_raise(rb_eArgError, "Unexpected value-type `%s'", rb_obj_classname(value)); } return value; }
Clear this Window and remove all stored text.
win.clear => #<Subtlext::Window:xxx>
VALUE subextWindowClear(int argc, VALUE *argv, VALUE self) { SubtlextWindow *w = NULL; /* Check ruby object */ rb_check_frozen(self); Data_Get_Struct(self, SubtlextWindow, w); if(w) { VALUE x = Qnil, y = Qnil, width = Qnil, height = Qnil; rb_scan_args(argc, argv, "04", &x, &y, &width, &height); /* Either clear area or whole window */ if(FIXNUM_P(x) && FIXNUM_P(y) && FIXNUM_P(width) && FIXNUM_P(height)) { XClearArea(display, w->win, FIX2INT(x), FIX2INT(y), FIX2INT(width), FIX2INT(height), False); } else XClearWindow(display, w->win); } return self; }
Draw a icon on the Window starting at x/y with given width, height and color without caching it.
win.draw_icon(10, 10, Subtlext::Icon.new("foo.xbm")) => #<Subtlext::Window:xxx>
VALUE subextWindowDrawIcon(int argc, VALUE *argv, VALUE self) { SubtlextWindow *w = NULL; VALUE x = Qnil, y = Qnil, icon = Qnil, fg = Qnil, bg = Qnil; /* Check ruby object */ rb_check_frozen(self); rb_scan_args(argc, argv, "32", &x, &y, &icon, &fg, &bg); Data_Get_Struct(self, SubtlextWindow, w); if(w && FIXNUM_P(x) && FIXNUM_P(y) && rb_obj_is_instance_of(icon, rb_const_get(mod, rb_intern("Icon")))) { int bitmap = False; long lfg = w->fg, lbg = w->bg; VALUE width = Qnil, height = Qnil, pixmap = Qnil; /* Create on demand */ if(0 == w->gc) w->gc = XCreateGC(display, w->win, 0, NULL); /* Parse colors */ if(!NIL_P(fg)) lfg = subextColorPixel(fg, Qnil, Qnil, NULL); if(!NIL_P(bg)) lbg = subextColorPixel(bg, Qnil, Qnil, NULL); /* Fetch icon values */ width = rb_iv_get(icon, "@width"); height = rb_iv_get(icon, "@height"); pixmap = rb_iv_get(icon, "@pixmap"); bitmap = Qtrue == subextIconAskBitmap(icon) ? True : False; subSharedDrawIcon(display, w->gc, w->win, FIX2INT(x), FIX2INT(y), FIX2INT(width), FIX2INT(height), lfg, lbg, NUM2LONG(pixmap), bitmap); } return self; }
Draw a line on the window starting at x1/y1 to x2/y2 in given color.
win.draw_line(1, 1, 10, 1) => #<Subtlext::Window:xxx> win.draw_line(1, 1, 10, 1, "#ff0000", "#000000") => #<Subtlext::Window:xxx>
VALUE subextWindowDrawLine(int argc, VALUE *argv, VALUE self) { VALUE x1 = Qnil, x2 = Qnil, y1 = Qnil, y2 = Qnil, color = Qnil; rb_scan_args(argc, argv, "41", &x1, &y1, &x2, &y2, &color); /* Check object types */ if(FIXNUM_P(x1) && FIXNUM_P(y1) && FIXNUM_P(x2) && FIXNUM_P(x2)) { SubtlextWindow *w = NULL; Data_Get_Struct(self, SubtlextWindow, w); if(w) { XGCValues gvals; /* Create on demand */ if(0 == w->gc) w->gc = XCreateGC(display, w->win, 0, NULL); /* Update GC */ gvals.foreground = w->fg; gvals.background = w->bg; if(!NIL_P(color)) gvals.foreground = subextColorPixel(color, Qnil, Qnil, NULL); XChangeGC(display, w->gc, GCForeground|GCBackground, &gvals); XDrawLine(display, w->win, w->gc, FIX2INT(x1), FIX2INT(y1), FIX2INT(x2), FIX2INT(y2)); XFlush(display); } } else rb_raise(rb_eArgError, "Unexpected value-types"); return self; }
Draw a pixel on the window at given coordinates in given color.
win.draw_point(1, 1) => #<Subtlext::Window:xxx> win.draw_point(1, 1, "#ff0000") => #<Subtlext::Window:xxx>
VALUE subextWindowDrawPoint(int argc, VALUE *argv, VALUE self) { VALUE x = Qnil, y = Qnil, color = Qnil; rb_scan_args(argc, argv, "21", &x, &y, &color); /* Check object types */ if(FIXNUM_P(x) && FIXNUM_P(y)) { SubtlextWindow *w = NULL; Data_Get_Struct(self, SubtlextWindow, w); if(w) { XGCValues gvals; /* Create on demand */ if(0 == w->gc) w->gc = XCreateGC(display, w->win, 0, NULL); /* Update GC */ gvals.foreground = w->fg; gvals.background = w->bg; if(!NIL_P(color)) gvals.foreground = subextColorPixel(color, Qnil, Qnil, NULL); XChangeGC(display, w->gc, GCForeground|GCBackground, &gvals); XDrawPoint(display, w->win, w->gc, FIX2INT(x), FIX2INT(y)); XFlush(display); } } else rb_raise(rb_eArgError, "Unexpected value-types"); return self; }
Draw a rect on the Window starting at x/y with given width, height and colors.
win.draw_rect(1, 1, 10, 10) => #<Subtlext::Window:xxx> win.draw_rect(1, 1, 10, 10, "#ff0000", true) => #<Subtlext::Window:xxx>
VALUE subextWindowDrawRect(int argc, VALUE *argv, VALUE self) { VALUE x = Qnil, y = Qnil, width = Qnil, height = Qnil; VALUE color = Qnil, fill = Qnil; rb_scan_args(argc, argv, "42", &x, &y, &width, &height, &color, &fill); /* Check object types */ if(FIXNUM_P(x) && FIXNUM_P(y) && FIXNUM_P(width) && FIXNUM_P(height)) { SubtlextWindow *w = NULL; Data_Get_Struct(self, SubtlextWindow, w); if(w) { XGCValues gvals; /* Create on demand */ if(0 == w->gc) w->gc = XCreateGC(display, w->win, 0, NULL); /* Update GC */ gvals.foreground = w->fg; gvals.background = w->bg; if(!NIL_P(color)) gvals.foreground = subextColorPixel(color, Qnil, Qnil, NULL); XChangeGC(display, w->gc, GCForeground|GCBackground, &gvals); /* Draw rect */ if(Qtrue == fill) { XFillRectangle(display, w->win, w->gc, FIX2INT(x), FIX2INT(y), FIX2INT(width), FIX2INT(height)); } else XDrawRectangle(display, w->win, w->gc, FIX2INT(x), FIX2INT(y), FIX2INT(width), FIX2INT(height)); XFlush(display); } } else rb_raise(rb_eArgError, "Unexpected value-types"); return self; }
Draw a text on the Window starting at x/y with given width, height and color without caching it.
win.draw_text(10, 10, "subtle") => #<Subtlext::Window:xxx>
VALUE subextWindowDrawText(int argc, VALUE *argv, VALUE self) { SubtlextWindow *w = NULL; VALUE x = Qnil, y = Qnil, text = Qnil, color = Qnil; /* Check ruby object */ rb_check_frozen(self); rb_scan_args(argc, argv, "31", &x, &y, &text, &color); Data_Get_Struct(self, SubtlextWindow, w); if(w && FIXNUM_P(x) && FIXNUM_P(y) && T_STRING == rb_type(text)) { long lcolor = w->fg; /* Create on demand */ if(0 == w->gc) w->gc = XCreateGC(display, w->win, 0, NULL); /* Parse colors */ if(!NIL_P(color)) lcolor = subextColorPixel(color, Qnil, Qnil, NULL); subSharedDrawString(display, w->gc, w->font, w->win, FIX2INT(x), FIX2INT(y), lcolor, w->bg, RSTRING_PTR(text), RSTRING_LEN(text)); } return self; }
Whether both objects have the same value and types (based on win)
object1.eql? object2 => true
static VALUE SubtlextEqualTypedWindow(VALUE self, VALUE other) { return SubtlextEqual(self, other, "@win", True); }
Set focus to window
object.focus => nil
static VALUE SubtlextFocus(VALUE self) { VALUE win = Qnil; SubMessageData data = { { 0, 0, 0, 0, 0 } }; /* Check ruby object */ rb_check_frozen(self); GET_ATTR(self, "@win", win); /* Send message */ data.l[0] = NUM2LONG(win); subSharedMessage(display, ROOT, "_NET_ACTIVE_WINDOW", data, 32, True); return self; }
Set the font that is used for text inside of a W.indow
win.font = "-*-*-*-*-*-*-10-*-*-*-*-*-*-*" => "-*-*-*-*-*-*-10-*-*-*-*-*-*-*"
VALUE subextWindowFontWriter(VALUE self, VALUE value) { SubtlextWindow *w = NULL; /* Check ruby object */ rb_check_frozen(self); Data_Get_Struct(self, SubtlextWindow, w); if(w) { /* Check object type */ if(T_STRING == rb_type(value)) { SubFont *f = NULL; char *font = RSTRING_PTR(value); /* Create window font */ if((f = subSharedFontNew(display, font))) { /* Replace font */ if(w->font) subSharedFontKill(display, w->font); w->font = f; } else rb_raise(rb_eStandardError, "Invalid font `%s'", font); } else rb_raise(rb_eArgError, "Unexpected value-type `%s'", rb_obj_classname(value)); } return value; }
Get the height of selected Window font.
win.font_height => 10
VALUE subextWindowFontHeightReader(VALUE self) { VALUE ret = INT2FIX(0); SubtlextWindow *w = NULL; /* Check ruby object */ rb_check_frozen(self); Data_Get_Struct(self, SubtlextWindow, w); if(w && w->font) ret = INT2FIX(w->font->height); return ret; }
Get width of string for selected Window font.
win.font_width("subtle") => 10
VALUE subextWindowFontWidth(VALUE self, VALUE string) { VALUE ret = INT2FIX(0); SubtlextWindow *w = NULL; /* Check ruby object */ rb_check_frozen(self); Data_Get_Struct(self, SubtlextWindow, w); if(w && w->font && T_STRING == rb_type(string)) ret = INT2FIX(subSharedStringWidth(display, w->font, RSTRING_PTR(string), RSTRING_LEN(string), NULL, NULL, False)); return ret; }
Get y offset of the selected Window font.
win.font_y => 10
VALUE subextWindowFontYReader(VALUE self) { VALUE ret = INT2FIX(0); SubtlextWindow *w = NULL; /* Check ruby object */ rb_check_frozen(self); Data_Get_Struct(self, SubtlextWindow, w); if(w && w->font) ret = INT2FIX(w->font->y); return ret; }
Set the foreground color of this Window which can be of following types:
String |
Any color representation of Xlib is allowed |
Array |
Must be an array with values for red, green and blue |
Hash |
Must be a hash with values for red, green and blue |
Fixnum |
Pixel representation of a color in Xlib |
Object |
Copy color from a Color object |
win.foreground = "#000000" => "#000000"
VALUE subextWindowForegroundWriter(VALUE self, VALUE value) { SubtlextWindow *w = NULL; /* Check ruby object */ rb_check_frozen(self); Data_Get_Struct(self, SubtlextWindow, w); if(w) w->fg = subextColorPixel(value, Qnil, Qnil, NULL); return value; }
VALUE subextWindowGeometryReader(VALUE self) { VALUE geom = Qnil; /* Check ruby object */ rb_check_frozen(self); GET_ATTR(self, "@geometry", geom); return geom; }
Set the geometry of this Window which can be of following types:
Array |
Must be an array with values for x, y, width and height |
Hash |
Must be a hash with values for x, y, width and height |
Geometry |
Copy geometry from a Geometry object |
win.geometry = { :x => 0, :y => 0, :width => 50, :height => 50 } => { :x => 0, :y => 0, :width => 50, :height => 50 }
VALUE subextWindowGeometryWriter(VALUE self, VALUE value) { SubtlextWindow *w = NULL; /* Check ruby object */ rb_check_frozen(self); Data_Get_Struct(self, SubtlextWindow, w); if(w) { XRectangle r = { 0 }; VALUE geom = Qnil; /* Create geometry */ geom = subextGeometryInstantiate(0, 0, 1, 1); geom = subextGeometryInit(1, &value, geom); rb_iv_set(self, "@geometry", geom); subextGeometryToRect(geom, &r); XMoveResizeWindow(display, w->win, r.x, r.y, r.width, r.height); } return value; }
Hide this Window from screen.
win.hide => #<Subtlext::Window:xxx>
VALUE subextWindowHide(VALUE self) { VALUE win = Qnil; /* Check ruby object */ rb_check_frozen(self); GET_ATTR(self, "@win", win); if(RTEST(win)) { rb_iv_set(self, "@hidden", Qtrue); XUnmapWindow(display, NUM2LONG(win)); XSync(display, False); ///< Sync with X } return self; }
Destroy this Window and freeze this object.
win.kill => nil
VALUE subextWindowKill(VALUE self) { SubtlextWindow *w = NULL; /* Check ruby object */ rb_check_frozen(self); Data_Get_Struct(self, SubtlextWindow, w); if(w) { XUnmapWindow(display, w->win); rb_obj_freeze(self); ///< Freeze object } return Qnil; }
Lower this Window to the bottom of the window stack, when the window manager supports that. (subtle does)
win.lower => #<Subtlext::Window:xxx>
VALUE subextWindowLower(VALUE self) { SubtlextWindow *w = NULL; /* Check ruby object */ rb_check_frozen(self); Data_Get_Struct(self, SubtlextWindow, w); if(w) { XLowerWindow(display, w->win); WindowExpose(w); } return self; }
Set the WM_NAME of a Window-
win.name = "sublet" => "sublet"
VALUE subextWindowNameWriter(VALUE self, VALUE value) { SubtlextWindow *w = NULL; /* Check ruby object */ rb_check_frozen(self); Data_Get_Struct(self, SubtlextWindow, w); if(w) { Window win = None; XClassHint hint; XTextProperty text; char *name = NULL; /* Check object type */ if(T_STRING == rb_type(value)) { name = RSTRING_PTR(value); win = NUM2LONG(rb_iv_get(self, "@win")); /* Set Window informations */ hint.res_name = name; hint.res_class = "Subtlext"; XSetClassHint(display, win, &hint); XStringListToTextProperty(&name, 1, &text); XSetWMName(display, win, &text); free(text.value); } else rb_raise(rb_eArgError, "Unexpected value-type `%s'", rb_obj_classname(value)); } return value; }
Grab pointer button press events and pass them to the block until the return value of the block isn't true or an error occured.
grab_mouse do |x, y, button| p "x=#{x}, y=#{y}, button=#{button}" end => #<Subtlext::Window:xxx>
VALUE subextWindowOn(int argc, VALUE *argv, VALUE self) { VALUE event = Qnil, value = Qnil; SubtlextWindow *w = NULL; /* Check ruby object */ rb_check_frozen(self); rb_scan_args(argc, argv, "11", &event, &value); if(rb_block_given_p()) value = rb_block_proc(); ///< Get proc Data_Get_Struct(self, SubtlextWindow, w); if(w) { /* Check value type */ if(CHAR2SYM("draw") == event || CHAR2SYM("redraw") == event || CHAR2SYM("expose") == event) { w->expose = value; } else if(CHAR2SYM("key_down") == event) { w->keyboard = value; } else if(CHAR2SYM("mouse_down") == event) { w->pointer = value; } else rb_raise(rb_eArgError, "Unexpected value type for on"); } return self; }
Raise this Window to the top of the window stack, when the window manager supports that. (subtle does)
win.raise => #<Subtlext::Window:xxx>
VALUE subextWindowRaise(VALUE self) { SubtlextWindow *w = NULL; /* Check ruby object */ rb_check_frozen(self); Data_Get_Struct(self, SubtlextWindow, w); if(w) { XRaiseWindow(display, w->win); WindowExpose(w); } return self; }
Redraw Window content.
win.redraw => #<Subtlext::Window:xxx>
VALUE subextWindowRedraw(VALUE self) { SubtlextWindow *w = NULL; /* Check ruby object */ rb_check_frozen(self); Data_Get_Struct(self, SubtlextWindow, w); if(w) WindowExpose(w); return self; }
Emulate a click on a window with optional button and x/y position
object.send_button => nil object.send_button(2) => Object
static VALUE SubtlextSendButton(int argc, VALUE *argv, VALUE self) { Window subwin = None; XEvent event = { 0 }; VALUE button = Qnil, x = Qnil, y = Qnil, win = Qnil; /* Check ruby object */ rb_check_frozen(self); GET_ATTR(self, "@win", win); rb_scan_args(argc, argv, "03", &button, &x, &y); /* Assemble button event */ event.type = EnterNotify; event.xcrossing.window = NUM2LONG(win); event.xcrossing.root = ROOT; event.xcrossing.subwindow = NUM2LONG(win); event.xcrossing.same_screen = True; event.xcrossing.x = FIXNUM_P(x) ? FIX2INT(x) : 5; event.xcrossing.y = FIXNUM_P(y) ? FIX2INT(y) : 5; /* Translate window x/y to root x/y */ XTranslateCoordinates(display, event.xcrossing.window, event.xcrossing.root, event.xcrossing.x, event.xcrossing.y, &event.xcrossing.x_root, &event.xcrossing.y_root, &subwin); //XSetInputFocus(display, event.xany.window, RevertToPointerRoot, CurrentTime); XSendEvent(display, NUM2LONG(win), True, EnterWindowMask, &event); /* Send button press event */ event.type = ButtonPress; event.xbutton.button = FIXNUM_P(button) ? FIX2INT(button) : 1; XSendEvent(display, NUM2LONG(win), True, ButtonPressMask, &event); XFlush(display); usleep(12000); /* Send button release event */ event.type = ButtonRelease; XSendEvent(display, NUM2LONG(win), True, ButtonReleaseMask, &event); XFlush(display); return self; }
Emulate a keypress on a window
object.send_key("d") => Object
static VALUE SubtlextSendKey(int argc, VALUE *argv, VALUE self) { VALUE keys = Qnil, x = Qnil, y = Qnil, win = Qnil; /* Check ruby object */ rb_check_frozen(self); GET_ATTR(self, "@win", win); rb_scan_args(argc, argv, "12", &keys, &x, &y); /* Check object type */ if(T_STRING == rb_type(keys)) { int mouse = False; unsigned int code = 0, state = 0; char *tokens = NULL, *tok = NULL, *save = NULL; Window subwin = None; KeySym sym = None; XEvent event = { 0 }; /* Assemble enter event */ event.type = EnterNotify; event.xcrossing.window = NUM2LONG(win); event.xcrossing.root = ROOT; event.xcrossing.subwindow = NUM2LONG(win); event.xcrossing.same_screen = True; event.xcrossing.x = FIXNUM_P(x) ? FIX2INT(x) : 5; event.xcrossing.y = FIXNUM_P(y) ? FIX2INT(y) : 5; /* Translate window x/y to root x/y */ XTranslateCoordinates(display, event.xcrossing.window, event.xcrossing.root, event.xcrossing.x, event.xcrossing.y, &event.xcrossing.x_root, &event.xcrossing.y_root, &subwin); XSendEvent(display, NUM2LONG(win), True, EnterWindowMask, &event); /* Parse keys */ tokens = strdup(RSTRING_PTR(keys)); tok = strtok_r(tokens, " ", &save); while(tok) { /* Parse key chain */ if(NoSymbol == (sym = subSharedParseKey(display, tok, &code, &state, &mouse))) { rb_raise(rb_eStandardError, "Unknown key"); return Qnil; } /* Check mouse */ if(True == mouse) { rb_raise(rb_eNotImpError, "Use #send_button instead"); return Qnil; } #ifdef HAVE_X11_EXTENSIONS_XTEST_H XTestGrabControl(display, True); /* Send key press/release events */ SubtlextSendModifier(state, True); XTestFakeKeyEvent(display, code, True, CurrentTime); XTestFakeKeyEvent(display, code, False, CurrentTime); SubtlextSendModifier(state, False); XTestGrabControl(display, False); #else /* HAVE_X11_EXTENSIONS_XTEST_H */ /* Send key press event */ event.type = KeyPress; event.xkey.state = state; event.xkey.keycode = code; XSendEvent(display, NUM2LONG(win), True, KeyPressMask, &event); XFlush(display); usleep(12000); /* Send key release event */ event.type = KeyRelease; XSendEvent(display, NUM2LONG(win), True, KeyReleaseMask, &event); #endif /* HAVE_X11_EXTENSIONS_XTEST_H */ tok = strtok_r(NULL, " ", &save); } XFlush(display); free(tokens); } else rb_raise(rb_eArgError, "Unexpected value-type `%s'", rb_obj_classname(keys)); return self; }
Show this Window on screen.
win.show => #<Subtlext::Window:xxx>
VALUE subextWindowShow(VALUE self) { SubtlextWindow *w = NULL; /* Check ruby object */ rb_check_frozen(self); Data_Get_Struct(self, SubtlextWindow, w); if(w) { rb_iv_set(self, "@hidden", Qfalse); if(RTEST(w->keyboard) || RTEST(w->pointer)) WindowGrab(w); else { XMapRaised(display, w->win); WindowExpose(w); } } return self; }
subextWindowSubwindow {{{
Create a subwindow of Window with given Geometry.
win.subwindow(:x => 5, :y => 5) do |w| s.background = "#ffffff" end
VALUE subextWindowSubwindow(VALUE self, VALUE geometry) { VALUE ret = Qnil; SubtlextWindow *w1 = NULL; Data_Get_Struct(self, SubtlextWindow, w1); if(w1) { SubtlextWindow *w2 = NULL; subextSubtlextConnect(NULL); ///< Implicit open connection ret = subextWindowInstantiate(geometry); Data_Get_Struct(ret, SubtlextWindow, w2); if(w2) { /* Yield to block if given */ if(rb_block_given_p()) rb_yield_values(1, w2->instance); XReparentWindow(display, w2->win, w1->win, 0, 0); } } return ret; }