mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 08:00:42 -05:00
Make dialogs that Metacity shows follow focus-stealing-prevention
2004-08-25 Elijah Newren <newren@math.utah.edu> Make dialogs that Metacity shows follow focus-stealing-prevention conventions. (fixes one issue in #149028; see comments 47-54) * src/delete.c (delete_ping_reply_func, delete_ping_timeout_func): Make callback functions take a timestamp arg, (delete_ping_timeout_func): pass the timestamp to metacity-dialog * src/display.c (meta_display_ping_timeout): add a timestamp to the call to the ping_timeout_func, (meta_display_ping_window, process_pong_message): add a timestamp to the call to the ping_reply_func * src/display.h (MetaWindowPingFunc typedef): add a timestamp to this function typedef * src/keybindings.c (error_on_command): require a timestamp and pass the timestamp on to metacity-dialog, (handle_run_command): pass a timestamp to error_on_command * src/metacity-dialog.c (copy_of_gdk_x11_window_set_user_time): new function (temporary; only for use while using gtk+-2.4), (kill_window_question, warn_about_no_sm_support, error_about_command): make these functions take a timestamp and call copy_of_gdk_x11_window_set_user_time, (main): require the first two args to the program to be "--timestamp <timestamp>" * src/session.c (warn_about_lame_clients_and_finish_inter): pass a timestamp of 0 to metacity-dialog to prevent focus (it's a popup not generated by and kind of user request).
This commit is contained in:
parent
07c406cad9
commit
044d8999a3
33
ChangeLog
33
ChangeLog
@ -1,3 +1,36 @@
|
|||||||
|
2004-08-25 Elijah Newren <newren@math.utah.edu>
|
||||||
|
|
||||||
|
Make dialogs that Metacity shows follow focus-stealing-prevention
|
||||||
|
conventions. (fixes one issue in #149028; see comments 47-54)
|
||||||
|
|
||||||
|
* src/delete.c (delete_ping_reply_func,
|
||||||
|
delete_ping_timeout_func): Make callback functions take a
|
||||||
|
timestamp arg, (delete_ping_timeout_func): pass the timestamp to
|
||||||
|
metacity-dialog
|
||||||
|
|
||||||
|
* src/display.c (meta_display_ping_timeout): add a timestamp to
|
||||||
|
the call to the ping_timeout_func, (meta_display_ping_window,
|
||||||
|
process_pong_message): add a timestamp to the call to the
|
||||||
|
ping_reply_func
|
||||||
|
|
||||||
|
* src/display.h (MetaWindowPingFunc typedef): add a timestamp to
|
||||||
|
this function typedef
|
||||||
|
|
||||||
|
* src/keybindings.c (error_on_command): require a timestamp and
|
||||||
|
pass the timestamp on to metacity-dialog, (handle_run_command):
|
||||||
|
pass a timestamp to error_on_command
|
||||||
|
|
||||||
|
* src/metacity-dialog.c (copy_of_gdk_x11_window_set_user_time):
|
||||||
|
new function (temporary; only for use while using gtk+-2.4),
|
||||||
|
(kill_window_question, warn_about_no_sm_support,
|
||||||
|
error_about_command): make these functions take a timestamp and
|
||||||
|
call copy_of_gdk_x11_window_set_user_time, (main): require the
|
||||||
|
first two args to the program to be "--timestamp <timestamp>"
|
||||||
|
|
||||||
|
* src/session.c (warn_about_lame_clients_and_finish_inter): pass a
|
||||||
|
timestamp of 0 to metacity-dialog to prevent focus (it's a popup
|
||||||
|
not generated by and kind of user request).
|
||||||
|
|
||||||
Fri Aug 20 12:54:12 2004 Soeren Sandmann <sandmann@daimi.au.dk>
|
Fri Aug 20 12:54:12 2004 Soeren Sandmann <sandmann@daimi.au.dk>
|
||||||
|
|
||||||
* src/display.c (meta_display_end_grab_op): Move wireframe code
|
* src/display.c (meta_display_end_grab_op): Move wireframe code
|
||||||
|
16
src/delete.c
16
src/delete.c
@ -38,6 +38,7 @@ static void meta_window_present_delete_dialog (MetaWindow *window);
|
|||||||
static void
|
static void
|
||||||
delete_ping_reply_func (MetaDisplay *display,
|
delete_ping_reply_func (MetaDisplay *display,
|
||||||
Window xwindow,
|
Window xwindow,
|
||||||
|
Time timestamp,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_PING,
|
meta_topic (META_DEBUG_PING,
|
||||||
@ -290,14 +291,16 @@ io_from_ping_dialog (GIOChannel *channel,
|
|||||||
static void
|
static void
|
||||||
delete_ping_timeout_func (MetaDisplay *display,
|
delete_ping_timeout_func (MetaDisplay *display,
|
||||||
Window xwindow,
|
Window xwindow,
|
||||||
|
Time timestamp,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
MetaWindow *window = user_data;
|
MetaWindow *window = user_data;
|
||||||
GError *err;
|
GError *err;
|
||||||
int child_pid;
|
int child_pid;
|
||||||
int outpipe;
|
int outpipe;
|
||||||
char *argv[7];
|
char *argv[9];
|
||||||
char numbuf[32];
|
char numbuf[32];
|
||||||
|
char timestampbuf[32];
|
||||||
char *window_id_str;
|
char *window_id_str;
|
||||||
GIOChannel *channel;
|
GIOChannel *channel;
|
||||||
|
|
||||||
@ -314,14 +317,17 @@ delete_ping_timeout_func (MetaDisplay *display,
|
|||||||
window_id_str = g_strdup_printf ("0x%lx", window->xwindow);
|
window_id_str = g_strdup_printf ("0x%lx", window->xwindow);
|
||||||
|
|
||||||
sprintf (numbuf, "%d", window->screen->number);
|
sprintf (numbuf, "%d", window->screen->number);
|
||||||
|
sprintf (timestampbuf, "%lu", timestamp);
|
||||||
|
|
||||||
argv[0] = METACITY_LIBEXECDIR"/metacity-dialog";
|
argv[0] = METACITY_LIBEXECDIR"/metacity-dialog";
|
||||||
argv[1] = "--screen";
|
argv[1] = "--screen";
|
||||||
argv[2] = numbuf;
|
argv[2] = numbuf;
|
||||||
argv[3] = "--kill-window-question";
|
argv[3] = "--timestamp";
|
||||||
argv[4] = window->title;
|
argv[4] = timestampbuf;
|
||||||
argv[5] = window_id_str;
|
argv[5] = "--kill-window-question";
|
||||||
argv[6] = NULL;
|
argv[6] = window->title;
|
||||||
|
argv[7] = window_id_str;
|
||||||
|
argv[8] = NULL;
|
||||||
|
|
||||||
err = NULL;
|
err = NULL;
|
||||||
if (!g_spawn_async_with_pipes ("/",
|
if (!g_spawn_async_with_pipes ("/",
|
||||||
|
@ -3675,7 +3675,7 @@ meta_display_ping_timeout (gpointer data)
|
|||||||
ping_data->timestamp, ping_data->xwindow);
|
ping_data->timestamp, ping_data->xwindow);
|
||||||
|
|
||||||
(* ping_data->ping_timeout_func) (ping_data->display, ping_data->xwindow,
|
(* ping_data->ping_timeout_func) (ping_data->display, ping_data->xwindow,
|
||||||
ping_data->user_data);
|
ping_data->timestamp, ping_data->user_data);
|
||||||
|
|
||||||
ping_data->display->pending_pings =
|
ping_data->display->pending_pings =
|
||||||
g_slist_remove (ping_data->display->pending_pings,
|
g_slist_remove (ping_data->display->pending_pings,
|
||||||
@ -3704,7 +3704,7 @@ meta_display_ping_window (MetaDisplay *display,
|
|||||||
if (!window->net_wm_ping)
|
if (!window->net_wm_ping)
|
||||||
{
|
{
|
||||||
if (ping_reply_func)
|
if (ping_reply_func)
|
||||||
(* ping_reply_func) (display, window->xwindow, user_data);
|
(* ping_reply_func) (display, window->xwindow, timestamp, user_data);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -3830,7 +3830,9 @@ process_pong_message (MetaDisplay *display,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Call callback */
|
/* Call callback */
|
||||||
(* ping_data->ping_reply_func) (display, ping_data->xwindow,
|
(* ping_data->ping_reply_func) (display,
|
||||||
|
ping_data->xwindow,
|
||||||
|
ping_data->timestamp,
|
||||||
ping_data->user_data);
|
ping_data->user_data);
|
||||||
|
|
||||||
ping_data_free (ping_data);
|
ping_data_free (ping_data);
|
||||||
|
@ -69,6 +69,7 @@ typedef struct _MetaGroupPropHooks MetaGroupPropHooks;
|
|||||||
|
|
||||||
typedef void (* MetaWindowPingFunc) (MetaDisplay *display,
|
typedef void (* MetaWindowPingFunc) (MetaDisplay *display,
|
||||||
Window xwindow,
|
Window xwindow,
|
||||||
|
Time timestamp,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
|
|
||||||
|
@ -2486,12 +2486,14 @@ static void
|
|||||||
error_on_command (int command_index,
|
error_on_command (int command_index,
|
||||||
const char *command,
|
const char *command,
|
||||||
const char *message,
|
const char *message,
|
||||||
int screen_number)
|
int screen_number,
|
||||||
|
Time timestamp)
|
||||||
{
|
{
|
||||||
GError *err;
|
GError *err;
|
||||||
char *argv[8];
|
char *argv[10];
|
||||||
char *key;
|
char *key;
|
||||||
char numbuf[32];
|
char numbuf[32];
|
||||||
|
char timestampbuf[32];
|
||||||
|
|
||||||
meta_warning ("Error on command %d \"%s\": %s\n",
|
meta_warning ("Error on command %d \"%s\": %s\n",
|
||||||
command_index, command, message);
|
command_index, command, message);
|
||||||
@ -2499,15 +2501,18 @@ error_on_command (int command_index,
|
|||||||
key = meta_prefs_get_gconf_key_for_command (command_index);
|
key = meta_prefs_get_gconf_key_for_command (command_index);
|
||||||
|
|
||||||
sprintf (numbuf, "%d", screen_number);
|
sprintf (numbuf, "%d", screen_number);
|
||||||
|
sprintf (timestampbuf, "%lu", timestamp);
|
||||||
|
|
||||||
argv[0] = METACITY_LIBEXECDIR"/metacity-dialog";
|
argv[0] = METACITY_LIBEXECDIR"/metacity-dialog";
|
||||||
argv[1] = "--screen";
|
argv[1] = "--screen";
|
||||||
argv[2] = numbuf;
|
argv[2] = numbuf;
|
||||||
argv[3] = "--command-failed-error";
|
argv[3] = "--timestamp";
|
||||||
argv[4] = key;
|
argv[4] = timestampbuf;
|
||||||
argv[5] = (char*) (command ? command : "");
|
argv[5] = "--command-failed-error";
|
||||||
argv[6] = (char*) message;
|
argv[6] = key;
|
||||||
argv[7] = NULL;
|
argv[7] = (char*) (command ? command : "");
|
||||||
|
argv[8] = (char*) message;
|
||||||
|
argv[9] = NULL;
|
||||||
|
|
||||||
err = NULL;
|
err = NULL;
|
||||||
if (!g_spawn_async_with_pipes ("/",
|
if (!g_spawn_async_with_pipes ("/",
|
||||||
@ -2596,7 +2601,7 @@ handle_run_command (MetaDisplay *display,
|
|||||||
|
|
||||||
s = g_strdup_printf (_("No command %d has been defined.\n"),
|
s = g_strdup_printf (_("No command %d has been defined.\n"),
|
||||||
which + 1);
|
which + 1);
|
||||||
error_on_command (which, NULL, s, screen->number);
|
error_on_command (which, NULL, s, screen->number, event->xkey.time);
|
||||||
g_free (s);
|
g_free (s);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -2605,7 +2610,7 @@ handle_run_command (MetaDisplay *display,
|
|||||||
err = NULL;
|
err = NULL;
|
||||||
if (!meta_spawn_command_line_async_on_screen (command, screen, &err))
|
if (!meta_spawn_command_line_async_on_screen (command, screen, &err))
|
||||||
{
|
{
|
||||||
error_on_command (which, command, err->message, screen->number);
|
error_on_command (which, command, err->message, screen->number, event->xkey.time);
|
||||||
|
|
||||||
g_error_free (err);
|
g_error_free (err);
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,30 @@
|
|||||||
#define N_(x) x
|
#define N_(x) x
|
||||||
|
|
||||||
#include <gdk/gdkx.h>
|
#include <gdk/gdkx.h>
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
|
||||||
|
/* FIXME: When we switch to gtk+-2.6, use of this function should be
|
||||||
|
* replaced by using the real gdk_x11_window_set_user_time.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
copy_of_gdk_x11_window_set_user_time (GdkWindow *window,
|
||||||
|
Time timestamp)
|
||||||
|
{
|
||||||
|
GdkDisplay *display;
|
||||||
|
|
||||||
|
g_return_if_fail (window != NULL);
|
||||||
|
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||||
|
|
||||||
|
if (GDK_WINDOW_DESTROYED (window))
|
||||||
|
return;
|
||||||
|
|
||||||
|
display = gdk_drawable_get_display (window);
|
||||||
|
|
||||||
|
XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
|
||||||
|
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_USER_TIME"),
|
||||||
|
XA_CARDINAL, 32, PropModeReplace,
|
||||||
|
(guchar *)×tamp, 1);
|
||||||
|
}
|
||||||
|
|
||||||
static Window
|
static Window
|
||||||
window_from_string (const char *str)
|
window_from_string (const char *str)
|
||||||
@ -76,7 +100,8 @@ on_realize (GtkWidget *dialog,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
kill_window_question (const char *window_name,
|
kill_window_question (const char *window_name,
|
||||||
const char *parent_str)
|
const char *parent_str,
|
||||||
|
Time timestamp)
|
||||||
{
|
{
|
||||||
GtkWidget *dialog;
|
GtkWidget *dialog;
|
||||||
char *str, *tmp;
|
char *str, *tmp;
|
||||||
@ -109,6 +134,9 @@ kill_window_question (const char *window_name,
|
|||||||
g_signal_connect (G_OBJECT (dialog), "realize",
|
g_signal_connect (G_OBJECT (dialog), "realize",
|
||||||
G_CALLBACK (on_realize), (char*) parent_str);
|
G_CALLBACK (on_realize), (char*) parent_str);
|
||||||
|
|
||||||
|
gtk_widget_realize (dialog);
|
||||||
|
copy_of_gdk_x11_window_set_user_time (dialog->window, timestamp);
|
||||||
|
|
||||||
/* return our PID, then window ID that should be killed */
|
/* return our PID, then window ID that should be killed */
|
||||||
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
|
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
|
||||||
g_print ("%d\n%s\n", (int) getpid (), parent_str);
|
g_print ("%d\n%s\n", (int) getpid (), parent_str);
|
||||||
@ -220,7 +248,8 @@ create_lame_apps_list (char **lame_apps)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
warn_about_no_sm_support (char **lame_apps)
|
warn_about_no_sm_support (char **lame_apps,
|
||||||
|
Time timestamp)
|
||||||
{
|
{
|
||||||
GtkWidget *dialog;
|
GtkWidget *dialog;
|
||||||
GtkWidget *list;
|
GtkWidget *list;
|
||||||
@ -267,6 +296,9 @@ warn_about_no_sm_support (char **lame_apps)
|
|||||||
sw,
|
sw,
|
||||||
TRUE, TRUE, 0);
|
TRUE, TRUE, 0);
|
||||||
|
|
||||||
|
gtk_widget_realize (dialog);
|
||||||
|
copy_of_gdk_x11_window_set_user_time (dialog->window, timestamp);
|
||||||
|
|
||||||
gtk_widget_show_all (dialog);
|
gtk_widget_show_all (dialog);
|
||||||
|
|
||||||
gtk_main ();
|
gtk_main ();
|
||||||
@ -277,7 +309,8 @@ warn_about_no_sm_support (char **lame_apps)
|
|||||||
static int
|
static int
|
||||||
error_about_command (const char *gconf_key,
|
error_about_command (const char *gconf_key,
|
||||||
const char *command,
|
const char *command,
|
||||||
const char *error)
|
const char *error,
|
||||||
|
Time timestamp)
|
||||||
{
|
{
|
||||||
GtkWidget *dialog;
|
GtkWidget *dialog;
|
||||||
|
|
||||||
@ -296,6 +329,9 @@ error_about_command (const char *gconf_key,
|
|||||||
GTK_BUTTONS_CLOSE,
|
GTK_BUTTONS_CLOSE,
|
||||||
"%s", error);
|
"%s", error);
|
||||||
|
|
||||||
|
gtk_widget_realize (dialog);
|
||||||
|
copy_of_gdk_x11_window_set_user_time (dialog->window, timestamp);
|
||||||
|
|
||||||
gtk_dialog_run (GTK_DIALOG (dialog));
|
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||||
|
|
||||||
gtk_widget_destroy (dialog);
|
gtk_widget_destroy (dialog);
|
||||||
@ -306,52 +342,61 @@ error_about_command (const char *gconf_key,
|
|||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
Time timestamp;
|
||||||
|
|
||||||
bindtextdomain (GETTEXT_PACKAGE, METACITY_LOCALEDIR);
|
bindtextdomain (GETTEXT_PACKAGE, METACITY_LOCALEDIR);
|
||||||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||||
textdomain (GETTEXT_PACKAGE);
|
textdomain (GETTEXT_PACKAGE);
|
||||||
|
|
||||||
gtk_init (&argc, &argv);
|
gtk_init (&argc, &argv);
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 4)
|
||||||
{
|
{
|
||||||
g_printerr ("bad args to metacity-dialog\n");
|
g_printerr ("bad args to metacity-dialog\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp (argv[1], "--kill-window-question") == 0)
|
if (strcmp (argv[1], "--timestamp") != 0)
|
||||||
{
|
{
|
||||||
if (argc < 4)
|
g_printerr ("bad args to metacity-dialog\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
timestamp = strtoul (argv[2], NULL, 10);
|
||||||
|
|
||||||
|
if (strcmp (argv[3], "--kill-window-question") == 0)
|
||||||
|
{
|
||||||
|
if (argc < 6)
|
||||||
{
|
{
|
||||||
g_printerr ("bad args to metacity-dialog\n");
|
g_printerr ("bad args to metacity-dialog\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return kill_window_question (argv[2], argv[3]);
|
return kill_window_question (argv[4], argv[5], timestamp);
|
||||||
}
|
}
|
||||||
else if (strcmp (argv[1], "--warn-about-no-sm-support") == 0)
|
else if (strcmp (argv[3], "--warn-about-no-sm-support") == 0)
|
||||||
{
|
{
|
||||||
/* argc must be even because we want title-class pairs */
|
/* argc must be even because we want title-class pairs */
|
||||||
if (argc < 3 || (argc % 2) != 0)
|
if (argc < 5 || (argc % 2) != 0)
|
||||||
{
|
{
|
||||||
g_printerr ("bad args to metacity-dialog\n");
|
g_printerr ("bad args to metacity-dialog\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return warn_about_no_sm_support (&argv[2]);
|
return warn_about_no_sm_support (&argv[4], timestamp);
|
||||||
}
|
}
|
||||||
else if (strcmp (argv[1], "--command-failed-error") == 0)
|
else if (strcmp (argv[3], "--command-failed-error") == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* the args are the gconf key of the failed command, the text of
|
/* the args are the gconf key of the failed command, the text of
|
||||||
* the command, and the error message
|
* the command, and the error message
|
||||||
*/
|
*/
|
||||||
if (argc != 5)
|
if (argc != 7)
|
||||||
{
|
{
|
||||||
g_printerr ("bad args to metacity-dialog\n");
|
g_printerr ("bad args to metacity-dialog\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return error_about_command (argv[2], argv[3], argv[4]);
|
return error_about_command (argv[4], argv[5], argv[6], timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_printerr ("bad args to metacity-dialog\n");
|
g_printerr ("bad args to metacity-dialog\n");
|
||||||
|
@ -1851,6 +1851,8 @@ warn_about_lame_clients_and_finish_interact (gboolean shutdown)
|
|||||||
GError *err;
|
GError *err;
|
||||||
GIOChannel *channel;
|
GIOChannel *channel;
|
||||||
LameClientsDialogData *d;
|
LameClientsDialogData *d;
|
||||||
|
Time timestamp;
|
||||||
|
char timestampbuf[32];
|
||||||
|
|
||||||
lame = NULL;
|
lame = NULL;
|
||||||
displays = meta_displays_list ();
|
displays = meta_displays_list ();
|
||||||
@ -1893,8 +1895,12 @@ warn_about_lame_clients_and_finish_interact (gboolean shutdown)
|
|||||||
|
|
||||||
lame = g_slist_sort (lame, (GCompareFunc) windows_cmp_by_title);
|
lame = g_slist_sort (lame, (GCompareFunc) windows_cmp_by_title);
|
||||||
|
|
||||||
|
timestamp = 0;
|
||||||
|
sprintf (timestampbuf, "%lu", timestamp);
|
||||||
|
|
||||||
len = g_slist_length (lame);
|
len = g_slist_length (lame);
|
||||||
len *= 2; /* titles and also classes */
|
len *= 2; /* titles and also classes */
|
||||||
|
len += 2; /* --timestamp flag and actual timestamp */
|
||||||
len += 1; /* NULL term */
|
len += 1; /* NULL term */
|
||||||
len += 2; /* metacity-dialog command and option */
|
len += 2; /* metacity-dialog command and option */
|
||||||
|
|
||||||
@ -1904,6 +1910,10 @@ warn_about_lame_clients_and_finish_interact (gboolean shutdown)
|
|||||||
|
|
||||||
argv[i] = METACITY_LIBEXECDIR"/metacity-dialog";
|
argv[i] = METACITY_LIBEXECDIR"/metacity-dialog";
|
||||||
++i;
|
++i;
|
||||||
|
argv[i] = "--timestamp";
|
||||||
|
++i;
|
||||||
|
argv[i] = timestampbuf;
|
||||||
|
++i;
|
||||||
argv[i] = "--warn-about-no-sm-support";
|
argv[i] = "--warn-about-no-sm-support";
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user