Saturday, August 29, 2009

install Chromium for Linux x86_64 on openSUSE

(continued from phosphorescence: Prepare to install Chromium for Linux x86_64 on openSUSE)

Let's start installation.

1st checkout depot_tools
> svn co http://src.chromium.org/svn/trunk/tools/depot_tools
...
> export PATH=`pwd`/depot_tools:"$PATH"

2nd, checkout chromium with Git: this takes a time (in my case it took 1.5 minutes).
> git clone --depth 1 git://git.chromium.org/chromium.git src

3rd, create gclient config file and edit.
> ./depot_tools/gclient config http://src.chromium.org/svn/trunk/src
Then I edit .gclient like below:
solutions = [
{ "name" : "src",
"url" : "http://src.chromium.org/svn/trunk/src",
"custom_deps" : {
# To use the trunk of a component instead of what's in DEPS:
#"component": "https://svnserver/component/trunk/",
# To exclude a component from your working copy:
#"data/really_large_component": None,
"src/third_party/WebKit/LayoutTests": None
},
"safesync_url": ""
}
]

4th, sync gclient: this takes a long time (in my case it took 15 minutes).
> ./depot_tools/gclient sync

Finally, build the chromium for x86_64: make takes so long long times (in my case it took 1.5 hours).
> ./src/tools/gyp/gyp -f make src/build/all.gyp -Dtarget_arch=x64
> cd src
> make CC="ccache gcc" CXX="ccache g++" -r BUILDTYPE=Release -j6 chrome V=1


And run the chromium.

Speaking of shortcomings, all related files of chromium (source, tools and binaries) spend lots of disk space.
> du -h --total /opt/chromium
...
2.4G /opt/chromium

Friday, August 28, 2009

Prepare to install Chromium for Linux x86_64 on openSUSE

1 week ago, Google announced Chromium had been ready for Linux x86_64. I learned in this article. So I started to install Chromium (Google Chrome for POSIX) on my openSUSE 11.1 x86_64. But, this was a very long way. So I decide to divide a post in two: "prepare to install" and "install". This entry is about prepare to install.

First, read documentations for downloading chromium and for building. Below 3 documents are useful.
Second, install the missing packages. If your Desktop environment is GNOME and if you install all major header files, don't worry about it. But if not - me the KDE user - some header files and packages are missing. For example, I add these packages and there dependencies: ccache, gpref, flex, bison, gtk2-devel, mozilla-nss-devel and gconf2-devel.

And last preparation, create installation root directory. For this time, I created /opt/chromium directory.
to be continued...

Tuesday, August 25, 2009

Method#parameters - Ruby 1.9.2 new feature

Most friendly new feature in Ruby 1.9.2 is Method#parameters. What is this? see the sample below:
> /opt/ruby-1.9.1/bin/irb
irb(main):001:0> def sample_method(a, b=0, *c, &d);end
=> nil
irb(main):002:0> self.method(:sample_method).parameters
=> [[:req, :a], [:opt, :b], [:rest, :c], [:block, :d]]

As you see, Method#parameters returns 2-dimensional array, not hash.

In each inner array, the first is parameter type and the last is parameter name. Parameter type is represented by symbol; :req is normal parameter, :opt is parameter with default value, :rest is variable parameter, and :block is block parameter.

Saturday, August 22, 2009

openSUSE benkyoukai 2009/08

Today, in Tokyo, openSUSE benkyoukai was held (What's benkyoukai? see the first part of past entry).

There was 1 session:
  • Script-Fu Tips of Gimp
But today, there are many lightning talks and its Q&As.
  • Renewal QtRuby
  • Program Semantics
  • screen command
At this time, I talked about "Renewal QtRuby".

Tuesday, August 18, 2009

drag move charm #2

(continued from phosphorescence: drag move charm #1)

Why sample widget cannot be moved with grabbing top level widget? It's handled in DragMoveCharm#event_filter method. I had surveyed and debugged this method. Then I found it is caused by incorrect decision of inheritance. See the example code:
> /opt/ruby-1.9.1/bin/irb
irb(main):001:0> require 'Qt'
=> true
irb(main):002:0> Qt::Application.new([])
=> #<Qt::Application:0x00000000c00918 objectName="irb">
irb(main):003:0> label = Qt::Label.new
=> #<Qt::Label:0x00000000befc58 objectName="", x=0, y=0, width=640, height=480>
irb(main):004:0> Qt::Label.ancestors
=> [Qt::Label, Qt::Frame, Qt::Widget, Qt::Object, Qt::PaintDevice, Object, Kernel, BasicObject]
irb(main):005:0> Qt::Label.ancestors.collect do |ancestor_class|
irb(main):006:1* label.is_a? ancestor_class
irb(main):007:1> end
=> [true, false, false, false, false, true, true, true]

After QtRuby 2.0.3, class method Module.ancestors returns not only Ruby's super classes but also Qt's super classes because Qt::Base class overrides this method. But, other related methods don't. Object#is_a? and its alias Object#kind_of? aren't overrode.

If override? Let's try:
> /opt/ruby-1.9.1/bin/irb
irb(main):001:0> require 'Qt'
=> true
irb(main):002:0> module Qt
irb(main):003:1> class Base
irb(main):004:2> def is_a?(mod)
irb(main):005:3> super || self.class.ancestors.include?(mod)
irb(main):006:3> end
irb(main):007:2> end
irb(main):008:1> end
=> nil
irb(main):009:0> Qt::Application.new([])
=> #<Qt::Application:0x00000000ba5c98 objectName="irb">
irb(main):010:0> label = Qt::Label.new
=> #<Qt::Label:0x00000000b94c40 objectName="", x=0, y=0, width=640, height=480>
irb(main):011:0> Qt::Label.ancestors
=> [Qt::Label, Qt::Frame, Qt::Widget, Qt::Object, Qt::PaintDevice, Object, Kernel, BasicObject]
irb(main):012:0> Qt::Label.ancestors.collect do |ancestor_class|
irb(main):013:1* label.is_a? ancestor_class
irb(main):014:1> end
=> [true, true, true, true, true, true, true, true]

It looks like well. So adding below code to override is_a? and kind_of? before execution.
unless Qt::Base.instance_methods(false).include?(:is_a?)
module Qt
class Base
def is_a?(mod)
super || self.class.ancestors.include?(mod)
end
alias :kind_of? :is_a?
end
end
end


Finally, run and move with grabbing top level widget successfully. See widget class code is here, and execution code is here.

Monday, August 17, 2009

drag move charm #1

When we want to move a window on the desktop, we grab the title bar of the window, move it with keeping on grabbing, and release it. Thus we can do it with title bar, but cannot otherwise.

In the graphics-dojo's example "drag move charm", we can move the window not only with grabbing title bar, but also with grabbing top level widget. I learn this example and start to write by QtRuby like below:
require 'Qt4'

class DragMoveData
attr_accessor :moving, :start_drag
alias :moving? :moving
end

class DragMoveCharm < Qt::Object

def initialize parent = nil
super
@drag_move_data = {}
end

def activate_on widget
unless @drag_move_data.include?(widget)
data = DragMoveData.new
data.start_drag = Qt::Point.new(0, 0)
data.moving = false
@drag_move_data[widget] = data
widget.install_event_filter(self)
end
end

def deactivate_from widget
@drag_move_data.delete(widget)
widget.remove_event_filter(self)
end

protected
def event_filter(widget, event)
consumed = widget.is_a?(Qt::Widget)
if consumed
type = event.type
case(type)
when Qt::Event::MouseButtonPress,
Qt::Event::MouseButtonRelease,
Qt::Event::MouseMove
consumed = event.kind_of?(Qt::MouseEvent) &&
event.modifiers == Qt::NoModifier &&
@drag_move_data.include?(widget)
if consumed
data = @drag_move_data[widget]
case(type)
when Qt::Event::MouseButtonPress
consumed = event.button == Qt::LeftButton
if consumed
data.start_drag = event.global_pos
data.moving = true
end
when Qt::Event::MouseButtonRelease
data.start_drag = Qt::Point.new(0, 0)
data.moving = false
consumed = false
when Qt::Event::MouseMove
consumed = data.moving?
if consumed
pos = event.global_pos
widget.move(widget.pos + pos - data.start_drag)
data.start_drag = pos;
end
end
end
else
consumed = false
end
end
consumed
end

alias :eventFilter :event_filter
end

and main codes to execute above classes:
require 'dragmovecharm'
require 'qtwebkit'

def image_show
Qt::Label.new do
self.text = "<img src='#{::File.dirname($PROGRAM_NAME)}/pudding.jpg'>"
self.adjust_size
self.window_title = 'Drag to move around'
show
end
end

def mini_browser
Qt::Dialog.new do
self.layout = Qt::VBoxLayout.new do
self.set_contents_margins(3, 15, 3, 3)
end
self.window_flags = Qt::FramelessWindowHint
self.size_grip_enabled = true
self.window_title = 'Drag to move around'
show

tab = Qt::TabWidget.new(self) do
search = Qt::WebView.new(self)
search.load(Qt::Url.new('http://www.google.com/m?hl=en'))
search.set_focus
self.add_tab(search, 'Search')
news = Qt::WebView.new(self)
news.load(Qt::Url.new('http://www.google.com/m/news?source=mobileproducts'))
self.add_tab(news, 'News')
bbc = Qt::WebView.new(self)
bbc.load(Qt::Url.new('http://news.bbc.co.uk/text_only.stm'))
self.add_tab(bbc, 'BBC')
fb = Qt::WebView.new(self)
fb.load(Qt::Url.new('http://iphone.facebook.com'))
self.add_tab(fb, 'Facebook')
end

self.layout.add_widget(tab)
self.resize(350, 500)
(tab.document_mode = true) if Qt::version >= '4.5'
end
end

Qt::Application.new(ARGV) do
charm = DragMoveCharm.new
charm.activate_on(image_show)
charm.activate_on(mini_browser)
exec
end

Run these codes, 2 charms(widgets) is shown successfully.

But, these can only be moved with grabbing title bar. These yet cannot be moved with grabbing top level widget. to be continued...

Friday, August 14, 2009

Qt Development Frameworks

3 days ago, Nokia announced they had changed Qt project name like below:
BeforeAfter
Qt Software->Qt Development Frameworks

Not only that, they are on changing project's web address. For example, top page goes like below:
BeforeAfter
http://www.qtsoftware.com/->http://qt.nokia.com/

And, documentation page goes:
BeforeAfter
http://doc.qtsoftware.com/->http://qt.nokia.com/doc/

So I had to fix documentation URI on my past entries. Now, I fixed all.

Tuesday, August 11, 2009

ruby-debug for Ruby 1.9

Ruby develop team had wanted a person who knows both Ruby 1.9 and ruby-debug very well to work ruby-debug on Ruby 1.9, as I wrote in phosphorescence: The 2nd day of RubyKaigi 2009 (Morning). Of course, Ruby 1.9 users too. When I read InfoQ's this article this morning, I knew that Ruby 1.9 ruby-debug project had launched. See below URL.

http://github.com/mark-moseley/ruby-debug/tree/master

Saturday, August 8, 2009

We (GUI Ruby user) still need CRuby

2 weeks ago, Charles Nutter(JRuby Core Developer) said JRuby's importance in his blog. I have 2 opinions (i.e. agree/disagree) for this entry.

Thursday, August 6, 2009

Ruby MinGW one-click installer (developing)

I found One-Click Ruby Installer for Windows MinGW edition a few days ago. This project is still developing now.

Qt SDK for Windows is built with MinGW. So I think it's advantageous building QtRuby on Windows using MinGW.

Monday, August 3, 2009

DigiFlip

I add some sample programs to my graphics-dojo clone repository. 'DigiFlip' sample(the one of added programs this time) is not simple-rewritable one from Qt to QtRuby. There are some points hard to implement. I will now list these.

point 1: Qt::Painter#setBrush
point 2: Qt::Pixmap#fill
  • It's similar with above point. A type of Qt::transparent is Qt::GlobalColor, but argument type of Qt::Pixmap#fill is Qt::Color. So Qt::GlobalColor object have to be wrapped with Qt::Color class.

point 3: Enum
  • This sample program manages 3 switching mode with enums: Slide, Flip, and Rotate. These are constants and declared as Qt::Enum instance. See also phosphorescence: Qt::Enum.

point 4: Qt::Painter#begin
  • If point 1~3 solved, some warning still occur.
    QPaintEngine::setSystemRect: Should not be changed while engine is active
    This message tells "Forgetting the method call Qt::Painter#begin". So I add this call with checking whether Qt::Painter is active.
        p = Qt::Painter.new(self)
        p.begin(@pixmap) unless p.active?

After implement correctly, let's run it.

'DigiFlip' is here, and others are found from repository top.