Class Subtlext::Window < Object

Class for interaction with windows

Attributes

hidden [R] Window visibility
win [R] Window id

Public class methods

new(geometry, &block) → Subtlext::Window

subextWindowInit {{{

Initialize Window object.

1 win = Subtlext::Window.new(:x => 5, :y => 5) do |w|
2   s.background = "#ffffff"
3 end
[show source]
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;
}
once(geometry) → Value

Show window once as long as proc runs

1 Subtlext::Window.once(:x => 10, :y => 10, :widht => 100, :height => 100) do |w|
2   "test"
3 end
4 => "test"
[show source]
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

<=>(other) → -1, 0 or 1

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)

1 object1 <=> object2
2 => 0
[show source]
static VALUE
SubtlextEqualSpaceWindow(VALUE self,
  VALUE other)
{
  return SubtlextSpaceship(self, other, "@win");
}
==(other) → True or False

Whether both objects have the same values (based on win)

1 object1 == object2
2 => true
[show source]
static VALUE
SubtlextEqualWindow(VALUE self,
  VALUE other)
{
  return SubtlextEqual(self, other, "@win", False);
}
[value] → String or Nil

Get arbitrary persistent property string or symbol value

1 object["wm"]
2 => "subtle"
3 
4 object[:wm]
5 => "subtle"
[show source]
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;
}
[key]= value → Nil

Set arbitrary persistent property string or symbol value

Symbols are implictly converted to string, to remove a property just set it to nil.

1 object["wm"] = "subtle"
2 => nil
3 
4 object[:wm] = "subtle"
5 => nil
6 
7 object[:wm] = nil
8 => nil
[show source]
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;
}
background=(string) → String
background=(array) → Array
background=(hash) → Hash
background=(fixnum) → Fixnum
background=(object) → Subtlext::Color

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
1 win.background = "#000000"
2 => "#000000"
[show source]
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;
}
border=(string) → String
border=(array) → Array
border=(hash) → Hash
border=(fixnum) → Fixnum
border=(object) → Subtlext::Color

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
1 win.border_color = "#000000"
2 => "#000000"
[show source]
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;
}
border_size=(fixnum) → Fixnum

Set border size of this Window.

1 win.border_size = 3
2 => 3
[show source]
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 → Subtlext::Window

Clear this Window and remove all stored text.

1 win.clear
2 => #<Subtlext::Window:xxx>
[show source]
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;
}
click (...)

Alias for send_button

draw_icon(x, y, icon, fg, bg) → Subtlext::Window

Draw a icon on the Window starting at x/y with given width, height and color without caching it.

1 win.draw_icon(10, 10, Subtlext::Icon.new("foo.xbm"))
2 => #<Subtlext::Window:xxx>
[show source]
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_line(x1, y1, x2, y2, color) → Subtlext::Window

Draw a line on the window starting at x1/y1 to x2/y2 in given color.

1 win.draw_line(1, 1, 10, 1)
2 => #<Subtlext::Window:xxx>
3 
4 win.draw_line(1, 1, 10, 1, "#ff0000", "#000000")
5 => #<Subtlext::Window:xxx>
[show source]
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_point(x, y, color) → Subtlext::Window

Draw a pixel on the window at given coordinates in given color.

1 win.draw_point(1, 1)
2 => #<Subtlext::Window:xxx>
3 
4 win.draw_point(1, 1, "#ff0000")
5 => #<Subtlext::Window:xxx>
[show source]
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_rect(x, y, width, height, color, fill) → Subtlext::Window

Draw a rect on the Window starting at x/y with given width, height and colors.

1 win.draw_rect(1, 1, 10, 10)
2 => #<Subtlext::Window:xxx>
3 
4 win.draw_rect(1, 1, 10, 10, "#ff0000", true)
5 => #<Subtlext::Window:xxx>
[show source]
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_text(x, y, string, color) → Subtlext::Window

Draw a text on the Window starting at x/y with given width, height and color without caching it.

1 win.draw_text(10, 10, "subtle")
2 => #<Subtlext::Window:xxx>
[show source]
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;
}
eql?(other) → True or False

Whether both objects have the same value and types (based on win)

1 object1.eql? object2
2 => true
[show source]
static VALUE
SubtlextEqualTypedWindow(VALUE self,
  VALUE other)
{
  return SubtlextEqual(self, other, "@win", True);
}
focus → nil

Set focus to window

1 object.focus
2 => nil
[show source]
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;
}
font=(string) → String

Set the font that is used for text inside of a W.indow

1 win.font = "-*-*-*-*-*-*-10-*-*-*-*-*-*-*"
2 => "-*-*-*-*-*-*-10-*-*-*-*-*-*-*"
[show source]
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;
}
font_height → Fixnum

Get the height of selected Window font.

1 win.font_height
2 => 10
[show source]
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;
}
font_width(string) → Fixnum

Get width of string for selected Window font.

1 win.font_width("subtle")
2 => 10
[show source]
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;
}
font_y → Fixnum

Get y offset of the selected Window font.

1 win.font_y
2 => 10
[show source]
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;
}
foreground=(string) → String
foreground=(array) → Array
foreground=(hash) → Hash
foreground=(fixnum) → Fixnum
foreground=(object) → Subtlext::Color

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
1 win.foreground = "#000000"
2 => "#000000"
[show source]
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;
}
geometry → Subtlext::Geometry

Get the Geometry of this Window.

1 win.geometry
2 => #<Subtlext::Geometry:xxx>
[show source]
VALUE
subextWindowGeometryReader(VALUE self)
{
  VALUE geom = Qnil;

  /* Check ruby object */
  rb_check_frozen(self);
  GET_ATTR(self, "@geometry", geom);

  return geom;
}
geometry=(array) → Array
geometry=(hash) → Hash
geometry=(object) → Subtlext::Geometry

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
1 win.geometry = { :x => 0, :y => 0, :width => 50, :height => 50 }
2 => { :x => 0, :y => 0, :width => 50, :height => 50 }
[show source]
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;
}
hidden → true or false

Whether Window is hidden.

1 win.hidden?
2 => true
[show source]
VALUE
subextWindowAskHidden(VALUE self)
{
  VALUE hidden  = Qnil;

  /* Check ruby object */
  rb_check_frozen(self);
  GET_ATTR(self, "@hidden", hidden);

  return hidden;
}
hide() → Subtlext::Window

Hide this Window from screen.

1 win.hide
2 => #<Subtlext::Window:xxx>
[show source]
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;
}
kill() → nil

Destroy this Window and freeze this object.

1 win.kill
2 => nil
[show source]
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 → Subtlext::Window

Lower this Window to the bottom of the window stack, when the window manager supports that. (subtle does)

1 win.lower
2 => #<Subtlext::Window:xxx>
[show source]
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;
}
name=(str) → String

Set the WM_NAME of a Window-

1 win.name = "sublet"
2 => "sublet"
[show source]
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;
}
on(event, &block) → Subtlext::Window

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.

1 grab_mouse do |x, y, button|
2   p "x=#{x}, y=#{y}, button=#{button}"
3 end
4 => #<Subtlext::Window:xxx>
[show source]
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 → Subtlext::Window

Raise this Window to the top of the window stack, when the window manager supports that. (subtle does)

1 win.raise
2 => #<Subtlext::Window:xxx>
[show source]
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 → Subtlext::Window

Redraw Window content.

1 win.redraw
2 => #<Subtlext::Window:xxx>
[show source]
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;
}
send_button(button, x, y) → Object

Emulate a click on a window with optional button and x/y position

1 object.send_button
2 => nil
3 
4 object.send_button(2)
5 => Object
[show source]
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;
}
send_key(key, x, y) → Object

Emulate a keypress on a window

1 object.send_key("d")
2 => Object
[show source]
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() → Subtlext::Window

Show this Window on screen.

1 win.show
2 => #<Subtlext::Window:xxx>
[show source]
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;
}
subwindow(geometry, &block) → Subtlext::Window or nil

subextWindowSubwindow {{{

Create a subwindow of Window with given Geometry.

1 win.subwindow(:x => 5, :y => 5) do |w|
2   s.background = "#ffffff"
3 end
[show source]
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;
}