From 8afe2104e3bf0c8a74c80fd0eaf2a3ee490b1de7 Mon Sep 17 00:00:00 2001 From: LI Daobing Date: Sat, 22 Jun 2024 18:54:12 -0700 Subject: [PATCH] #604: cop/save image not work under Linux (#607) --- src/iptux/DialogBase.cpp | 50 +++++++++++++++++++++++++-------------- src/iptux/DialogBase.h | 12 +++++++--- src/iptux/DialogGroup.cpp | 1 + src/iptux/DialogPeer.cpp | 1 + 4 files changed, 43 insertions(+), 21 deletions(-) diff --git a/src/iptux/DialogBase.cpp b/src/iptux/DialogBase.cpp index de45fb00..45d5153d 100644 --- a/src/iptux/DialogBase.cpp +++ b/src/iptux/DialogBase.cpp @@ -812,10 +812,28 @@ void DialogBase::OnPasteClipboard(DialogBase*, GtkTextView* textview) { } } -gboolean DialogBase::OnImageButtonPress(DialogBase*, - GdkEventButton event, +void DialogBase::afterWindowCreated() { + g_return_if_fail(!m_imagePopupMenu); + + m_imagePopupMenu = GTK_MENU(gtk_menu_new()); + + GtkWidget* menu_item = gtk_menu_item_new_with_label(_("Save Image")); + gtk_menu_shell_append(GTK_MENU_SHELL(m_imagePopupMenu), menu_item); + g_signal_connect_swapped(menu_item, "activate", + G_CALLBACK(DialogBase::OnSaveImage), this); + + menu_item = gtk_menu_item_new_with_label(_("Copy Image")); + gtk_menu_shell_append(GTK_MENU_SHELL(m_imagePopupMenu), menu_item); + g_signal_connect_swapped(menu_item, "activate", + G_CALLBACK(DialogBase::OnCopyImage), this); + + gtk_menu_attach_to_widget(m_imagePopupMenu, GTK_WIDGET(getWindow()), NULL); +} + +gboolean DialogBase::OnImageButtonPress(DialogBase* self, + GdkEventButton* event, GtkEventBox* event_box) { - if (event.type != GDK_BUTTON_PRESS || event.button != 3) { + if (event->type != GDK_BUTTON_PRESS || event->button != 3) { return FALSE; } @@ -824,20 +842,10 @@ gboolean DialogBase::OnImageButtonPress(DialogBase*, LOG_ERROR("image not found in event box."); return FALSE; } + self->m_activeImage = GTK_IMAGE(image); - GtkWidget* menu = gtk_menu_new(); - GtkWidget* menu_item = gtk_menu_item_new_with_label(_("Save Image")); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - g_signal_connect_swapped(menu_item, "activate", - G_CALLBACK(DialogBase::OnSaveImage), image); - menu_item = gtk_menu_item_new_with_label(_("Copy Image")); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - g_signal_connect_swapped(menu_item, "activate", - G_CALLBACK(DialogBase::OnCopyImage), image); - gtk_widget_show_all(menu); - - gtk_menu_popup_at_pointer(GTK_MENU(menu), (GdkEvent*)&event); - g_signal_connect(menu, "hide", G_CALLBACK(gtk_widget_destroy), menu); + gtk_widget_show_all(GTK_WIDGET(self->m_imagePopupMenu)); + gtk_menu_popup_at_pointer(self->m_imagePopupMenu, (GdkEvent*)event); return TRUE; } @@ -872,7 +880,10 @@ void DialogBase::OnChatHistoryInsertChildAnchor(DialogBase* self, gtk_widget_show_all(event_box); } -void DialogBase::OnSaveImage(GtkImage* image) { +void DialogBase::OnSaveImage(DialogBase* self) { + GtkImage* image = self->m_activeImage; + g_return_if_fail(!!image); + const char* path = (const char*)g_object_get_data(G_OBJECT(image), kObjectKeyImagePath); if (!path) { @@ -909,7 +920,10 @@ void DialogBase::OnSaveImage(GtkImage* image) { gtk_widget_destroy(dialog); } -void DialogBase::OnCopyImage(GtkImage* image) { +void DialogBase::OnCopyImage(DialogBase* self) { + GtkImage* image = self->m_activeImage; + g_return_if_fail(!!image); + GdkPixbuf* pixbuf = gtk_image_get_pixbuf(image); if (!pixbuf) { LOG_ERROR("Failed to create pixbuf from image."); diff --git a/src/iptux/DialogBase.h b/src/iptux/DialogBase.h index 8f19eee7..e424882c 100644 --- a/src/iptux/DialogBase.h +++ b/src/iptux/DialogBase.h @@ -35,6 +35,8 @@ class DialogBase : public SessionAbstract, public sigc::trackable { void InitSublayerGeneral(); void ClearSublayerGeneral(); + void afterWindowCreated(); + void ScrollHistoryTextview(); virtual void OnNewMessageComing(); void NotifyUser(); @@ -83,14 +85,14 @@ class DialogBase : public SessionAbstract, public sigc::trackable { static void RemoveSelectedEnclosure(DialogBase* self); static void OnPasteClipboard(DialogBase* self, GtkTextView* textview); static gboolean OnImageButtonPress(DialogBase* self, - GdkEventButton event, + GdkEventButton* event, GtkEventBox* eventbox); static void OnChatHistoryInsertChildAnchor(DialogBase* self, const GtkTextIter* location, GtkTextChildAnchor* anchor, GtkTextBuffer* buffer); - static void OnSaveImage(GtkImage* self); - static void OnCopyImage(GtkImage* self); + static void OnSaveImage(DialogBase* self); + static void OnCopyImage(DialogBase* self); protected: Application* app; @@ -109,6 +111,10 @@ class DialogBase : public SessionAbstract, public sigc::trackable { int64_t totalsendsize; // 总计待发送大小(包括已发送) struct timeval lasktime; // 上一次更新UI的时间 guint timersend; // 发送文件界面更新计时器ID + + private: + GtkMenu* m_imagePopupMenu = 0; + GtkImage* m_activeImage = 0; }; } // namespace iptux diff --git a/src/iptux/DialogGroup.cpp b/src/iptux/DialogGroup.cpp index b8919fae..53fb9d49 100644 --- a/src/iptux/DialogGroup.cpp +++ b/src/iptux/DialogGroup.cpp @@ -221,6 +221,7 @@ GtkWindow* DialogGroup::CreateMainWindow() { }; g_action_map_add_action_entries(G_ACTION_MAP(window), win_entries, G_N_ELEMENTS(win_entries), this); + afterWindowCreated(); return GTK_WINDOW(window); } diff --git a/src/iptux/DialogPeer.cpp b/src/iptux/DialogPeer.cpp index ca39c075..f85ab195 100644 --- a/src/iptux/DialogPeer.cpp +++ b/src/iptux/DialogPeer.cpp @@ -235,6 +235,7 @@ GtkWindow* DialogPeer::CreateMainWindow() { MainWindowSignalSetup(GTK_WINDOW(window)); g_signal_connect_swapped(GTK_WIDGET(window), "show", G_CALLBACK(ShowDialogPeer), this); + afterWindowCreated(); return GTK_WINDOW(window); }