Tkabber

Changes On Branch optimize_chat_roster
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch optimize_chat_roster Excluding Merge-Ins

This is equivalent to a diff from 04a7caac75 to 140aba8b35

2025-04-17
05:02
Merge optimization of chat rosters. check-in: f00591d976 user: sgolovan tags: trunk
04:58
Update ChangeLog. Leaf check-in: 140aba8b35 user: sgolovan tags: optimize_chat_roster
2025-04-16
13:57
* chats.tcl, plugins/chat/nick_colors.tcl: Cache the groupchat roster and not rebuild it every time it needs to be redrawn. check-in: 42aabdc9b0 user: sgolovan tags: optimize_chat_roster
2025-04-14
16:42
Add debug prints to collect info on chat roster redraws. check-in: 9ac74b784c user: sgolovan tags: optimize_chat_roster
2025-04-13
19:54
Do not override border widths and roster item placement indents (adapt theme examples to high DPI displays). Define colors for spinbox arrow buttons. check-in: 04a7caac75 user: sgolovan tags: trunk
18:38
Fix undefined priority for a light theme. Add missing roster background definitions for the unix default theme. check-in: 62c6f7a8f7 user: sgolovan tags: trunk

Changes to ChangeLog.





1
2
3
4
5
6
7
1
2
3
4
5
6
7
8
9
10
11
12
+
+
+
+
+







2025-04-16  Sergei Golovan  <sgolovan@nes.ru>

	* chats.tcl, plugins/chat/nick_colors.tcl: Cache the groupchat roster
	  and not rebuild it every time it needs to be redrawn.

2025-04-13  Sergei Golovan  <sgolovan@nes.ru>

	* plugins/unix/tktray.tcl: Add a workaround for a race condition in
	  Tcl 9 when the configure events for size of the tray icon come in
	  incorrect order.

	* tkabber.tcl: Determine by creating a text window whether the Tk
Changes to chats.tcl.
440
441
442
443
444
445
446










447
448
449
450
451
452
453
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463







+
+
+
+
+
+
+
+
+
+







    }

    hook::run open_chat_pre_hook $chatid $type

    set chats(type,$chatid) $type
    set chats(subject,$chatid) ""
    set chats(exit_status,$chatid) ""

    if {$type eq "groupchat"} {
        # Variable to hold groupchat roster items

        set chats(roster,$chatid) [dict create moderator {} \
                                               participant {} \
                                               visitor {} \
                                               user {}]
    }

    add_to_opened $chatid

    set chat_id($cw) $chatid

    lassign [chat::window_titles $chatid] chats(tabtitlename,$chatid) \
        chats(titlename,$chatid)

1106
1107
1108
1109
1110
1111
1112


1113

1114

1115
1116




























1117
1118
1119




















1120
1121
1122
1123
1124
1125




1126
1127
1128
1129

1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141

1142
1143
1144

1145
1146

1147
1148
1149
1150
1151
1152
1153



1154
1155
1156
1157

1158
1159
1160
1161

1162
1163

1164
1165
1166
1167
1168
1169


1170
1171

1172
1173
1174
1175
1176
1177
1178

1179
1180
1181

1182
1183
1184
1185
1186



1187
1188
1189
1190
1191
1192
1193
1116
1117
1118
1119
1120
1121
1122
1123
1124

1125
1126
1127


1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180




1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197

1198


1199



1200


1201







1202
1203
1204




1205

1206


1207


1208






1209
1210


1211
1212
1213
1214
1215
1216
1217

1218
1219
1220

1221
1222
1223



1224
1225
1226
1227
1228
1229
1230
1231
1232
1233







+
+
-
+

+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
-
-
-
+
+
+
+




+








-

-
-
+
-
-
-
+
-
-
+
-
-
-
-
-
-
-
+
+
+
-
-
-
-
+
-

-
-
+
-
-
+
-
-
-
-
-
-
+
+
-
-
+






-
+


-
+


-
-
-
+
+
+







}

hook::add client_presence_hook chat::change_presence 70

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

proc chat::process_roster_event {chatid jid nick status args} {
    variable chats

    debugmsg chat "ROSTER: $chatid $jid $nick $status"
    debugmsg chat "ROSTER: $chatid $jid $nick $status $args"

    if {$nick eq ""} return
    if {[string equal $nick ""]} return


    foreach role {moderator participant visitor user} {
        dict unset chats(roster,$chatid) $role $nick
    }

    if {$status ne "unavailable"} {
        set role user
        array set tmp $args
        switch -- $tmp(-role) {
            moderator -
            participant -
            visitor {
                set role $tmp(-role)
            }
            default {
                set role user
            }
        }

        if {$::plugins::nickcolors::options(use_colored_roster_nicks)} {
            set foreground [plugins::nickcolors::get_color $nick]
        } else {
            set foreground [ifacetk::roster::get_foreground $status]
        }

        dict set chats(roster,$chatid) $role $nick [list $jid $status $foreground]
    }

    chat::redraw_roster_after_idle $chatid
}

proc chat::update_roster_foregrounds {chatid} {
    variable chats

    foreach role {moderator participant visitor user} {
        dict for {nick val} [dict get $chats(roster,$chatid) $role] {
            lassign $val jid status foreground

            if {$::plugins::nickcolors::options(use_colored_roster_nicks)} {
                set foreground [plugins::nickcolors::get_color $nick]
            } else {
                set foreground [ifacetk::roster::get_foreground $status]
            }

            dict set chats(roster,$chatid) $role $nick [list $jid $status $foreground]
        }
    }

    chat::redraw_roster_after_idle $chatid
}

namespace eval chat {
    variable g2l
    array set g2l [list 1 [::msgcat::mc "Moderators"] \
                        2 [::msgcat::mc "Participants"] \
                        3 [::msgcat::mc "Visitors"] \
                        4 [::msgcat::mc "Users"]]
    array set g2l [list moderator   [::msgcat::mc "Moderators"] \
                        participant [::msgcat::mc "Participants"] \
                        visitor     [::msgcat::mc "Visitors"] \
                        user        [::msgcat::mc "Users"]]
}

proc chat::redraw_roster {chatid} {
    variable g2l
    variable chats

    set userswin [users_win $chatid]

    if {![winfo exists $userswin]} return

    ifacetk::roster::clear $userswin 0

    set xlib [get_xlib $chatid]
    set group [get_jid $chatid]

    set levels {}
    foreach nick [::muc::roster $chatid] {
    foreach role {moderator participant visitor user} {
        set jid $group/$nick
        set role [::muc::get_role $xlib $jid]

        set users [lsort -dictionary [dict keys [dict get $chats(roster,$chatid) $role]]]
        switch -- $role {
            moderator   {set level 1}
        set nusers [llength $users]
            participant {set level 2}
            visitor     {set level 3}
            default     {set level 4}
        }
        lappend levels $level
        lappend levelusers($level) [list $jid $nick]
    }
        if {$nusers == 0} {
            continue
        }
    set levels [lsort -unique $levels]

    foreach level $levels {
        ifacetk::roster::addline $userswin group \
        ifacetk::roster::addline $userswin group "$g2l($role) ($nusers)" $role $role {} 0
            "$g2l($level) ([llength $levelusers($level)])" $level $level {} 0

        foreach item [lsort -index 1 -dictionary $levelusers($level)] {
            lassign $item jid nick
        foreach nick $users {
            set status [get_user_status $xlib $jid]

            lassign [dict get $chats(roster,$chatid) $role $nick] jid status foreground
            if {$::plugins::nickcolors::options(use_colored_roster_nicks)} {
                set foreground [plugins::nickcolors::get_color $nick]
            } else {
                set foreground [ifacetk::roster::get_foreground $status]
            }
            ifacetk::roster::addline $userswin jid $nick \

            ifacetk::roster::addline $userswin jid $nick [list $xlib $jid] $role {} 0 \
                [list $xlib $jid] $level {} 0 \
                {} roster/user/$status $foreground
                                     {} roster/user/$status $foreground
        }
    }

    ifacetk::roster::update_scrollregion $userswin
}

proc chat::redraw_roster_after_idle {group} {
proc chat::redraw_roster_after_idle {chatid} {
    variable afterid

    if {[info exists afterid($group)]} \
    if {[info exists afterid($chatid)]} \
        return

    set afterid($group) [after idle "
        chat::redraw_roster [list $group]
        unset [list ::chat::afterid($group)]
    set afterid($chatid) [after idle "
        chat::redraw_roster [list $chatid]
        unset [list ::chat::afterid($chatid)]
    "]
}

proc chat::restore_subject {chatid} {
    variable chats

    set sw [winid $chatid].status.subject
Changes to plugins/chat/nick_colors.tcl.
259
260
261
262
263
264
265
266

267
268
269
270
271
272
273
259
260
261
262
263
264
265

266
267
268
269
270
271
272
273







-
+







    variable options
    variable NicksInChat

    foreach chatid [chat::opened] {
        set wn [chat::chat_win $chatid]
        if {[winfo exists $wn]} {
            if {[chat::is_groupchat $chatid]} {
                chat::redraw_roster_after_idle $chatid
                chat::update_roster_foregrounds $chatid
            }
            foreach nick $NicksInChat($chatid) {
                set clr [get_color $nick]
                $wn tag configure NICK-$nick \
                    -foreground [expr {$options(use_colored_nicks) ? $clr : ""}]
                $wn tag configure NICKMSG-$nick \
                    -foreground [expr {$options(use_colored_nicks) ? $clr : ""}]