Gtk2 IRC Client Sluggish and not Responsive


D

deadpickle

I am writing a Gtk2 IRC client (and have been for months now) and have
been having problems with it. The problems keep occuring as I try to
figure out a good way to handle incoming messages as well as out
going. One module Parse::IRC has done wonders in organizing the server
outputs. Right now the program starts a Glib::Timeout on connection
then IO::Selects the socket and listens to see if the socket can be
read. This is causing the Gtk2 part of the program to be sluggish and
non-responsive but the terminal window receives inputs just fine. What
I'm looking for is a way to make this program work smoother (and
please dont suggest using Net::IRC it has the same problems).

#!/usr/local/bin/perl -w
use strict;
use Gtk2 '-init';
use Glib qw/TRUE FALSE/;
use Parse::IRC;
use IO::Select;

my $chat_state = 'Connect';
my $channel = "#GRRUVI";
my $chat_entry;
my $chat_send_sig;
my $chat_textview;
my $chat_button;
my $tag;
my $job = 3;
my $sock;
my $parser = Parse::IRC->new( public => 1 );
my %dispatch = ( 'ping' => \&irc_ping, '001' => \&irc_001, 'public' =>
\&irc_public, 'quit' => \&irc_quit, 'join' => \&irc_join, '353' =>
\&irc_353);
my $irc = "irc.servercentral.net";
my $nick = "MetBase";
my $login = $nick;

my $post = 0;
my $msg;
my $who;
my $text;
my $sel = IO::Select->new();

#################################################
#Threads
#my $thread_chat = threads->new( \&chat);

#################################################

#-------------------Main Loop-------------------
&chat_build;

Gtk2->main;

####################CHAT BLOCK####################
#-------------------chat Build-------------------
sub chat_build {
my $chat_window = Gtk2::Window->new('toplevel');
$chat_window->set_title('Chat Client');
$chat_window->set_position('center');
$chat_window->set_default_size( 300, 300 );
$chat_window->signal_connect(delete_event=> sub{
Gtk2->main_quit;
});

$chat_entry = Gtk2::Entry->new;
my $chat_vbox = Gtk2::VBox->new;

#*********Removed Menu and Shortcuts*********#

my $chat_scroll = Gtk2::ScrolledWindow->new;
$chat_scroll->set_shadow_type( 'etched-out');
$chat_textview = Gtk2::TextView->new;
#$chat_entry = Gtk2::Entry->new;

my $chat_buffer = $chat_textview->get_buffer;
$chat_buffer->create_mark( 'end', $chat_buffer->get_end_iter,
FALSE );
$chat_buffer->signal_connect(insert_text => sub {
$chat_textview->scroll_to_mark( $chat_buffer->get_mark('end'),
0.0, TRUE, 0, 0.5 );
});
$chat_button = Gtk2::Button->new;
$chat_button->set_label($chat_state);


# allows for sending each line with an enter keypress
$chat_send_sig = $chat_entry->signal_connect ('key-press-event' =>
sub {
my ($widget,$event)= @_;
if( $event->keyval() == 65293){ # a return key press
my $text = $chat_entry->get_text;
print $sock "PRIVMSG $channel :$text\r\n";
$chat_entry->set_text('');
$chat_entry->set_position(0);
}
});

$chat_entry->signal_handler_block($chat_send_sig); #not connected
yet
$chat_entry->set_editable(0);
$chat_textview->set_editable(0);
$chat_textview->set_cursor_visible(0);
$chat_textview->set_wrap_mode('word');

$chat_scroll->add($chat_textview);
$chat_vbox->add($chat_scroll);
$chat_vbox->pack_start( $chat_entry, FALSE, FALSE, 0 );
$chat_vbox->pack_start( $chat_button, FALSE, FALSE, 0 );

$chat_window->add($chat_vbox);
$chat_window->show_all;

$chat_button->signal_connect("clicked" => sub {
if ($chat_state eq 'Connect') {
$chat_button->set_label('Disconnect');
$chat_state='Disconnect';
#$chat_start = 1;
&connecting;
}
else {
$chat_button->set_label('Connect');
$chat_state='Connect';
#$chat_start = 0;
}
});

#*********Removed Keyboard shortcuts and Output File
Creation*********#

return 1;
}

#-------------------Connect to IRC Server-------------------
sub connecting {
# Connect to the IRC server.
$sock = new IO::Socket::INET(
PeerAddr => $irc,
PeerPort => 6667,
Proto => 'tcp',
) or die "Can't connect\n";

print $sock "NICK $nick\r\n";
print $sock "USER $login 8 * :CoCoNUE Member $nick\r\n";

$sel->add($sock);

#################################################
#Timeout
my $timer_chat = Glib::Timeout->add(0.5, \&incoming_data);

#################################################

return 1;
}

#-------------------Watch for IRC Inputs-------------------
sub incoming_data {
if ($sel->can_read(1)){
print "got something\n";
my $input = <$sock>;

$input =~ s/\r\n//g;
my $hashref = $parser->parse( $input );
# print "2\n";
SWITCH: {
# print "3\n";
my $type = lc $hashref->{command};
my @args;
push @args, $hashref->{prefix} if $hashref->{prefix};
push @args, @{ $hashref->{params} };
if ( defined $dispatch{$type} ) {
# print "4\n";
$dispatch{$type}->(@args);
last SWITCH;
}
print STDOUT join( ' ', "irc_$type:", @args ), "\n";
# print "5\n";
}
}
return 1;
}

#*********Removed Message Posting in the GTK2 Window*********#

####################Chat parsers###################
#-------------------Ping-------------------
sub irc_ping {
my $server = shift;
print $sock "PONG :$server\r\n";
return 1;
}

#-------------------initial login-------------------
sub irc_001 {
$msg = $_[0];
$post = 2;
print STDOUT "Connected to $_[0]\n";
print $sock "JOIN $channel\r\n";
return 1;
}

#-------------------Public-------------------
sub irc_public {
my @sender = split(/!/, $_[0]);
$who = $sender[0];
$msg = $_[2];
$post = 5;
print "$who ->$msg \n";
return 1;
}

#-------------------Quit-------------------
sub irc_quit {
my @sender = split(/!/, $_[0]);
$who = $sender[0];
$msg = $channel;
$post = 4;
print "$who This is QUIT\n";
return 1;
}

#-------------------Join-------------------
sub irc_join {
my @sender = split(/!/, $_[0]);
$who = $sender[0];
$msg = $channel;
$post = 3;
print "$who This is Join\n";
return 1;
}

#-------------------List Users-------------------
sub irc_353 {
my ($who,$where,$what) = @_;
$msg = $_[4];
$post = 7;
print "$_[0] -> $_[1] -> $_[2] -> $_[3] -> $_[4]\n";
return 1;
}

#################################################
 
Ad

Advertisements


Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top