0

Split OutOfProcessInstance::HandleMessage() into smaller pieces.

HandleMessage() has gotten a bit too big. Move many message handlers
into their own methods.

Change-Id: Icc117a1056fdebe839b26defe3481b5416f0e014
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2242587
Reviewed-by: Daniel Hosseinian <dhoss@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#777976}
This commit is contained in:
Lei Zhang
2020-06-12 22:16:35 +00:00
committed by Commit Bot
parent 5d6841e81d
commit 03bc9c989c
2 changed files with 287 additions and 242 deletions

@ -552,163 +552,13 @@ void OutOfProcessInstance::HandleMessage(const pp::Var& message) {
std::string type = dict.Get(kType).AsString();
if (type == kJSViewportType) {
pp::Var layout_options_var = dict.Get(kJSLayoutOptions);
if (!layout_options_var.is_undefined()) {
DocumentLayout::Options layout_options;
layout_options.FromVar(layout_options_var);
// TODO(crbug.com/1013800): Eliminate need to get document size from here.
document_size_ = engine_->ApplyDocumentLayout(layout_options);
OnGeometryChanged(zoom_, device_scale_);
}
if (!(dict.Get(pp::Var(kJSXOffset)).is_number() &&
dict.Get(pp::Var(kJSYOffset)).is_number() &&
dict.Get(pp::Var(kJSZoom)).is_number() &&
dict.Get(pp::Var(kJSPinchPhase)).is_number())) {
NOTREACHED();
return;
}
received_viewport_message_ = true;
stop_scrolling_ = false;
PinchPhase pinch_phase =
static_cast<PinchPhase>(dict.Get(pp::Var(kJSPinchPhase)).AsInt());
double zoom = dict.Get(pp::Var(kJSZoom)).AsDouble();
double zoom_ratio = zoom / zoom_;
pp::FloatPoint scroll_offset(dict.Get(pp::Var(kJSXOffset)).AsDouble(),
dict.Get(pp::Var(kJSYOffset)).AsDouble());
if (pinch_phase == PINCH_START) {
scroll_offset_at_last_raster_ = scroll_offset;
last_bitmap_smaller_ = false;
needs_reraster_ = false;
return;
}
// When zooming in, we set a layer transform to avoid unneeded rerasters.
// Also, if we're zooming out and the last time we rerastered was when
// we were even further zoomed out (i.e. we pinch zoomed in and are now
// pinch zooming back out in the same gesture), we update the layer
// transform instead of rerastering.
if (pinch_phase == PINCH_UPDATE_ZOOM_IN ||
(pinch_phase == PINCH_UPDATE_ZOOM_OUT && zoom_ratio > 1.0)) {
if (!(dict.Get(pp::Var(kJSPinchX)).is_number() &&
dict.Get(pp::Var(kJSPinchY)).is_number() &&
dict.Get(pp::Var(kJSPinchVectorX)).is_number() &&
dict.Get(pp::Var(kJSPinchVectorY)).is_number())) {
NOTREACHED();
return;
}
pp::Point pinch_center(dict.Get(pp::Var(kJSPinchX)).AsDouble(),
dict.Get(pp::Var(kJSPinchY)).AsDouble());
// Pinch vector is the panning caused due to change in pinch
// center between start and end of the gesture.
pp::Point pinch_vector =
pp::Point(dict.Get(kJSPinchVectorX).AsDouble() * zoom_ratio,
dict.Get(kJSPinchVectorY).AsDouble() * zoom_ratio);
pp::Point scroll_delta;
// If the rendered document doesn't fill the display area we will
// use |paint_offset| to anchor the paint vertically into the same place.
// We use the scroll bars instead of the pinch vector to get the actual
// position on screen of the paint.
pp::Point paint_offset;
if (plugin_size_.width() > GetDocumentPixelWidth() * zoom_ratio) {
// We want to keep the paint in the middle but it must stay in the same
// position relative to the scroll bars.
paint_offset = pp::Point(0, (1 - zoom_ratio) * pinch_center.y());
scroll_delta =
pp::Point(0, (scroll_offset.y() -
scroll_offset_at_last_raster_.y() * zoom_ratio));
pinch_vector = pp::Point();
last_bitmap_smaller_ = true;
} else if (last_bitmap_smaller_) {
pinch_center = pp::Point((plugin_size_.width() / device_scale_) / 2,
(plugin_size_.height() / device_scale_) / 2);
const double zoom_when_doc_covers_plugin_width =
zoom_ * plugin_size_.width() / GetDocumentPixelWidth();
paint_offset = pp::Point(
(1 - zoom / zoom_when_doc_covers_plugin_width) * pinch_center.x(),
(1 - zoom_ratio) * pinch_center.y());
pinch_vector = pp::Point();
scroll_delta =
pp::Point((scroll_offset.x() -
scroll_offset_at_last_raster_.x() * zoom_ratio),
(scroll_offset.y() -
scroll_offset_at_last_raster_.y() * zoom_ratio));
}
paint_manager_.SetTransform(zoom_ratio, pinch_center,
pinch_vector + paint_offset + scroll_delta,
true);
needs_reraster_ = false;
return;
}
if (pinch_phase == PINCH_UPDATE_ZOOM_OUT || pinch_phase == PINCH_END) {
// We reraster on pinch zoom out in order to solve the invalid regions
// that appear after zooming out.
// On pinch end the scale is again 1.f and we request a reraster
// in the new position.
paint_manager_.ClearTransform();
last_bitmap_smaller_ = false;
needs_reraster_ = true;
// If we're rerastering due to zooming out, we need to update
// |scroll_offset_at_last_raster_|, in case the user continues the
// gesture by zooming in.
scroll_offset_at_last_raster_ = scroll_offset;
}
// Bound the input parameters.
zoom = std::max(kMinZoom, zoom);
DCHECK(dict.Get(pp::Var(kJSUserInitiated)).is_bool());
SetZoom(zoom);
scroll_offset = BoundScrollOffsetToDocument(scroll_offset);
engine_->ScrolledToXPosition(scroll_offset.x() * device_scale_);
engine_->ScrolledToYPosition(scroll_offset.y() * device_scale_);
HandleViewportMessage(dict);
} else if (type == kJSGetPasswordCompleteType) {
if (!dict.Get(pp::Var(kJSPassword)).is_string()) {
NOTREACHED();
return;
}
if (password_callback_) {
pp::CompletionCallbackWithOutput<pp::Var> callback = *password_callback_;
password_callback_.reset();
*callback.output() = dict.Get(pp::Var(kJSPassword)).pp_var();
callback.Run(PP_OK);
} else {
NOTREACHED();
}
HandleGetPasswordCompleteMessage(dict);
} else if (type == kJSPrintType) {
Print();
} else if (type == kJSSaveType) {
if (!(dict.Get(pp::Var(kJSToken)).is_string() &&
dict.Get(pp::Var(kJSSaveRequestType)).is_int())) {
NOTREACHED();
return;
}
const SaveRequestType request_type = static_cast<SaveRequestType>(
dict.Get(pp::Var(kJSSaveRequestType)).AsInt());
switch (request_type) {
case SaveRequestType::kAnnotation:
// In annotation mode, assume the user will make edits and prefer saving
// using the plugin data.
pp::PDF::SetPluginCanSave(this, true);
SaveToBuffer(dict.Get(pp::Var(kJSToken)).AsString());
break;
case SaveRequestType::kOriginal:
pp::PDF::SetPluginCanSave(this, false);
SaveToFile(dict.Get(pp::Var(kJSToken)).AsString());
pp::PDF::SetPluginCanSave(this, CanSaveEdits());
break;
case SaveRequestType::kEdited:
SaveToBuffer(dict.Get(pp::Var(kJSToken)).AsString());
break;
}
HandlePrintMessage(dict);
} else if (type == kJSRotateClockwiseType) {
RotateClockwise();
} else if (type == kJSRotateCounterclockwiseType) {
@ -718,101 +568,17 @@ void OutOfProcessInstance::HandleMessage(const pp::Var& message) {
} else if (type == kJSSelectAllType) {
engine_->SelectAll();
} else if (type == kJSBackgroundColorChangedType) {
if (!dict.Get(pp::Var(kJSBackgroundColor)).is_string()) {
NOTREACHED();
return;
}
base::HexStringToUInt(dict.Get(pp::Var(kJSBackgroundColor)).AsString(),
&background_color_);
HandleBackgroundColorChangedMessage(dict);
} else if (type == kJSResetPrintPreviewModeType) {
if (!(dict.Get(pp::Var(kJSPrintPreviewUrl)).is_string() &&
dict.Get(pp::Var(kJSPrintPreviewGrayscale)).is_bool() &&
dict.Get(pp::Var(kJSPrintPreviewPageCount)).is_int())) {
NOTREACHED();
return;
}
// For security reasons, crash if the URL that is trying to be loaded here
// isn't a print preview one.
std::string url = dict.Get(pp::Var(kJSPrintPreviewUrl)).AsString();
CHECK(IsPrintPreview());
CHECK(IsPrintPreviewUrl(url));
int print_preview_page_count =
dict.Get(pp::Var(kJSPrintPreviewPageCount)).AsInt();
if (print_preview_page_count < 0) {
NOTREACHED();
return;
}
// The page count is zero if the print preview source is a PDF. In which
// case, the page index for |url| should be at |kCompletePDFIndex|.
// When the page count is not zero, then the source is not PDF. In which
// case, the page index for |url| should be non-negative.
bool is_previewing_pdf = IsPreviewingPDF(print_preview_page_count);
int page_index = ExtractPrintPreviewPageIndex(url);
if (is_previewing_pdf) {
if (page_index != kCompletePDFIndex) {
NOTREACHED();
return;
}
} else {
if (page_index < 0) {
NOTREACHED();
return;
}
}
print_preview_page_count_ = print_preview_page_count;
print_preview_loaded_page_count_ = 0;
url_ = url;
preview_pages_info_ = base::queue<PreviewPageInfo>();
preview_document_load_state_ = LOAD_STATE_COMPLETE;
document_load_state_ = LOAD_STATE_LOADING;
LoadUrl(url_, /*is_print_preview=*/false);
preview_engine_.reset();
engine_ = PDFEngine::Create(this, false);
engine_->SetGrayscale(dict.Get(pp::Var(kJSPrintPreviewGrayscale)).AsBool());
engine_->New(url_.c_str(), nullptr /* empty header */);
paint_manager_.InvalidateRect(pp::Rect(pp::Point(), plugin_size_));
HandleResetPrintPreviewModeMessage(dict);
} else if (type == kJSLoadPreviewPageType) {
if (!(dict.Get(pp::Var(kJSPreviewPageUrl)).is_string() &&
dict.Get(pp::Var(kJSPreviewPageIndex)).is_int())) {
NOTREACHED();
return;
}
std::string url = dict.Get(pp::Var(kJSPreviewPageUrl)).AsString();
// For security reasons we crash if the URL that is trying to be loaded here
// isn't a print preview one.
CHECK(IsPrintPreview());
CHECK(IsPrintPreviewUrl(url));
ProcessPreviewPageInfo(url, dict.Get(pp::Var(kJSPreviewPageIndex)).AsInt());
HandleLoadPreviewPageMessage(dict);
} else if (type == kJSStopScrollingType) {
stop_scrolling_ = true;
} else if (type == kJSGetSelectedTextType) {
std::string selected_text = engine_->GetSelectedText();
// Always return unix newlines to JS.
base::ReplaceChars(selected_text, "\r", std::string(), &selected_text);
pp::VarDictionary reply;
reply.Set(pp::Var(kType), pp::Var(kJSGetSelectedTextReplyType));
reply.Set(pp::Var(kJSSelectedText), selected_text);
PostMessage(reply);
HandleGetSelectedTextMessage();
} else if (type == kJSGetNamedDestinationType) {
if (!dict.Get(pp::Var(kJSGetNamedDestination)).is_string()) {
NOTREACHED();
return;
}
base::Optional<PDFEngine::NamedDestination> named_destination =
engine_->GetNamedDestination(
dict.Get(pp::Var(kJSGetNamedDestination)).AsString());
pp::VarDictionary reply;
reply.Set(pp::Var(kType), pp::Var(kJSGetNamedDestinationReplyType));
reply.Set(
pp::Var(kJSNamedDestinationPageNumber),
named_destination ? static_cast<int>(named_destination->page) : -1);
PostMessage(reply);
HandleGetNamedDestinationMessage(dict);
} else {
NOTREACHED();
}
@ -1743,6 +1509,275 @@ std::string OutOfProcessInstance::GetFileNameFromUrl(const std::string& url) {
return base::UTF16ToUTF8(file_name);
}
void OutOfProcessInstance::HandleBackgroundColorChangedMessage(
const pp::VarDictionary& dict) {
if (!dict.Get(pp::Var(kJSBackgroundColor)).is_string()) {
NOTREACHED();
return;
}
base::HexStringToUInt(dict.Get(pp::Var(kJSBackgroundColor)).AsString(),
&background_color_);
}
void OutOfProcessInstance::HandleGetNamedDestinationMessage(
const pp::VarDictionary& dict) {
if (!dict.Get(pp::Var(kJSGetNamedDestination)).is_string()) {
NOTREACHED();
return;
}
base::Optional<PDFEngine::NamedDestination> named_destination =
engine_->GetNamedDestination(
dict.Get(pp::Var(kJSGetNamedDestination)).AsString());
pp::VarDictionary reply;
reply.Set(pp::Var(kType), pp::Var(kJSGetNamedDestinationReplyType));
reply.Set(pp::Var(kJSNamedDestinationPageNumber),
named_destination ? static_cast<int>(named_destination->page) : -1);
PostMessage(reply);
}
void OutOfProcessInstance::HandleGetPasswordCompleteMessage(
const pp::VarDictionary& dict) {
if (!dict.Get(pp::Var(kJSPassword)).is_string()) {
NOTREACHED();
return;
}
if (password_callback_) {
pp::CompletionCallbackWithOutput<pp::Var> callback = *password_callback_;
password_callback_.reset();
*callback.output() = dict.Get(pp::Var(kJSPassword)).pp_var();
callback.Run(PP_OK);
} else {
NOTREACHED();
}
}
void OutOfProcessInstance::HandleGetSelectedTextMessage() {
std::string selected_text = engine_->GetSelectedText();
// Always return unix newlines to JS.
base::ReplaceChars(selected_text, "\r", std::string(), &selected_text);
pp::VarDictionary reply;
reply.Set(pp::Var(kType), pp::Var(kJSGetSelectedTextReplyType));
reply.Set(pp::Var(kJSSelectedText), selected_text);
PostMessage(reply);
}
void OutOfProcessInstance::HandleLoadPreviewPageMessage(
const pp::VarDictionary& dict) {
if (!(dict.Get(pp::Var(kJSPreviewPageUrl)).is_string() &&
dict.Get(pp::Var(kJSPreviewPageIndex)).is_int())) {
NOTREACHED();
return;
}
std::string url = dict.Get(pp::Var(kJSPreviewPageUrl)).AsString();
// For security reasons we crash if the URL that is trying to be loaded here
// isn't a print preview one.
CHECK(IsPrintPreview());
CHECK(IsPrintPreviewUrl(url));
ProcessPreviewPageInfo(url, dict.Get(pp::Var(kJSPreviewPageIndex)).AsInt());
}
void OutOfProcessInstance::HandlePrintMessage(const pp::VarDictionary& dict) {
if (!(dict.Get(pp::Var(kJSToken)).is_string() &&
dict.Get(pp::Var(kJSSaveRequestType)).is_int())) {
NOTREACHED();
return;
}
const SaveRequestType request_type = static_cast<SaveRequestType>(
dict.Get(pp::Var(kJSSaveRequestType)).AsInt());
switch (request_type) {
case SaveRequestType::kAnnotation:
// In annotation mode, assume the user will make edits and prefer saving
// using the plugin data.
pp::PDF::SetPluginCanSave(this, true);
SaveToBuffer(dict.Get(pp::Var(kJSToken)).AsString());
break;
case SaveRequestType::kOriginal:
pp::PDF::SetPluginCanSave(this, false);
SaveToFile(dict.Get(pp::Var(kJSToken)).AsString());
pp::PDF::SetPluginCanSave(this, CanSaveEdits());
break;
case SaveRequestType::kEdited:
SaveToBuffer(dict.Get(pp::Var(kJSToken)).AsString());
break;
}
}
void OutOfProcessInstance::HandleResetPrintPreviewModeMessage(
const pp::VarDictionary& dict) {
if (!(dict.Get(pp::Var(kJSPrintPreviewUrl)).is_string() &&
dict.Get(pp::Var(kJSPrintPreviewGrayscale)).is_bool() &&
dict.Get(pp::Var(kJSPrintPreviewPageCount)).is_int())) {
NOTREACHED();
return;
}
// For security reasons, crash if the URL that is trying to be loaded here
// isn't a print preview one.
std::string url = dict.Get(pp::Var(kJSPrintPreviewUrl)).AsString();
CHECK(IsPrintPreview());
CHECK(IsPrintPreviewUrl(url));
int print_preview_page_count =
dict.Get(pp::Var(kJSPrintPreviewPageCount)).AsInt();
if (print_preview_page_count < 0) {
NOTREACHED();
return;
}
// The page count is zero if the print preview source is a PDF. In which
// case, the page index for |url| should be at |kCompletePDFIndex|.
// When the page count is not zero, then the source is not PDF. In which
// case, the page index for |url| should be non-negative.
bool is_previewing_pdf = IsPreviewingPDF(print_preview_page_count);
int page_index = ExtractPrintPreviewPageIndex(url);
if (is_previewing_pdf) {
if (page_index != kCompletePDFIndex) {
NOTREACHED();
return;
}
} else {
if (page_index < 0) {
NOTREACHED();
return;
}
}
print_preview_page_count_ = print_preview_page_count;
print_preview_loaded_page_count_ = 0;
url_ = url;
preview_pages_info_ = base::queue<PreviewPageInfo>();
preview_document_load_state_ = LOAD_STATE_COMPLETE;
document_load_state_ = LOAD_STATE_LOADING;
LoadUrl(url_, /*is_print_preview=*/false);
preview_engine_.reset();
engine_ = PDFEngine::Create(this, false);
engine_->SetGrayscale(dict.Get(pp::Var(kJSPrintPreviewGrayscale)).AsBool());
engine_->New(url_.c_str(), nullptr /* empty header */);
paint_manager_.InvalidateRect(pp::Rect(pp::Point(), plugin_size_));
}
void OutOfProcessInstance::HandleViewportMessage(
const pp::VarDictionary& dict) {
pp::Var layout_options_var = dict.Get(kJSLayoutOptions);
if (!layout_options_var.is_undefined()) {
DocumentLayout::Options layout_options;
layout_options.FromVar(layout_options_var);
// TODO(crbug.com/1013800): Eliminate need to get document size from here.
document_size_ = engine_->ApplyDocumentLayout(layout_options);
OnGeometryChanged(zoom_, device_scale_);
}
if (!(dict.Get(pp::Var(kJSXOffset)).is_number() &&
dict.Get(pp::Var(kJSYOffset)).is_number() &&
dict.Get(pp::Var(kJSZoom)).is_number() &&
dict.Get(pp::Var(kJSPinchPhase)).is_number())) {
NOTREACHED();
return;
}
received_viewport_message_ = true;
stop_scrolling_ = false;
PinchPhase pinch_phase =
static_cast<PinchPhase>(dict.Get(pp::Var(kJSPinchPhase)).AsInt());
double zoom = dict.Get(pp::Var(kJSZoom)).AsDouble();
double zoom_ratio = zoom / zoom_;
pp::FloatPoint scroll_offset(dict.Get(pp::Var(kJSXOffset)).AsDouble(),
dict.Get(pp::Var(kJSYOffset)).AsDouble());
if (pinch_phase == PINCH_START) {
scroll_offset_at_last_raster_ = scroll_offset;
last_bitmap_smaller_ = false;
needs_reraster_ = false;
return;
}
// When zooming in, we set a layer transform to avoid unneeded rerasters.
// Also, if we're zooming out and the last time we rerastered was when
// we were even further zoomed out (i.e. we pinch zoomed in and are now
// pinch zooming back out in the same gesture), we update the layer
// transform instead of rerastering.
if (pinch_phase == PINCH_UPDATE_ZOOM_IN ||
(pinch_phase == PINCH_UPDATE_ZOOM_OUT && zoom_ratio > 1.0)) {
if (!(dict.Get(pp::Var(kJSPinchX)).is_number() &&
dict.Get(pp::Var(kJSPinchY)).is_number() &&
dict.Get(pp::Var(kJSPinchVectorX)).is_number() &&
dict.Get(pp::Var(kJSPinchVectorY)).is_number())) {
NOTREACHED();
return;
}
pp::Point pinch_center(dict.Get(pp::Var(kJSPinchX)).AsDouble(),
dict.Get(pp::Var(kJSPinchY)).AsDouble());
// Pinch vector is the panning caused due to change in pinch
// center between start and end of the gesture.
pp::Point pinch_vector =
pp::Point(dict.Get(kJSPinchVectorX).AsDouble() * zoom_ratio,
dict.Get(kJSPinchVectorY).AsDouble() * zoom_ratio);
pp::Point scroll_delta;
// If the rendered document doesn't fill the display area we will
// use |paint_offset| to anchor the paint vertically into the same place.
// We use the scroll bars instead of the pinch vector to get the actual
// position on screen of the paint.
pp::Point paint_offset;
if (plugin_size_.width() > GetDocumentPixelWidth() * zoom_ratio) {
// We want to keep the paint in the middle but it must stay in the same
// position relative to the scroll bars.
paint_offset = pp::Point(0, (1 - zoom_ratio) * pinch_center.y());
scroll_delta = pp::Point(
0,
(scroll_offset.y() - scroll_offset_at_last_raster_.y() * zoom_ratio));
pinch_vector = pp::Point();
last_bitmap_smaller_ = true;
} else if (last_bitmap_smaller_) {
pinch_center = pp::Point((plugin_size_.width() / device_scale_) / 2,
(plugin_size_.height() / device_scale_) / 2);
const double zoom_when_doc_covers_plugin_width =
zoom_ * plugin_size_.width() / GetDocumentPixelWidth();
paint_offset = pp::Point(
(1 - zoom / zoom_when_doc_covers_plugin_width) * pinch_center.x(),
(1 - zoom_ratio) * pinch_center.y());
pinch_vector = pp::Point();
scroll_delta = pp::Point(
(scroll_offset.x() - scroll_offset_at_last_raster_.x() * zoom_ratio),
(scroll_offset.y() - scroll_offset_at_last_raster_.y() * zoom_ratio));
}
paint_manager_.SetTransform(zoom_ratio, pinch_center,
pinch_vector + paint_offset + scroll_delta,
true);
needs_reraster_ = false;
return;
}
if (pinch_phase == PINCH_UPDATE_ZOOM_OUT || pinch_phase == PINCH_END) {
// We reraster on pinch zoom out in order to solve the invalid regions
// that appear after zooming out.
// On pinch end the scale is again 1.f and we request a reraster
// in the new position.
paint_manager_.ClearTransform();
last_bitmap_smaller_ = false;
needs_reraster_ = true;
// If we're rerastering due to zooming out, we need to update
// |scroll_offset_at_last_raster_|, in case the user continues the
// gesture by zooming in.
scroll_offset_at_last_raster_ = scroll_offset;
}
// Bound the input parameters.
zoom = std::max(kMinZoom, zoom);
DCHECK(dict.Get(pp::Var(kJSUserInitiated)).is_bool());
SetZoom(zoom);
scroll_offset = BoundScrollOffsetToDocument(scroll_offset);
engine_->ScrolledToXPosition(scroll_offset.x() * device_scale_);
engine_->ScrolledToYPosition(scroll_offset.y() * device_scale_);
}
void OutOfProcessInstance::PreviewDocumentLoadComplete() {
if (preview_document_load_state_ != LOAD_STATE_LOADING ||
preview_pages_info_.empty()) {

@ -162,6 +162,16 @@ class OutOfProcessInstance : public pp::Instance,
static std::string GetFileNameFromUrl(const std::string& url);
private:
// Message handlers.
void HandleBackgroundColorChangedMessage(const pp::VarDictionary& dict);
void HandleGetNamedDestinationMessage(const pp::VarDictionary& dict);
void HandleGetPasswordCompleteMessage(const pp::VarDictionary& dict);
void HandleGetSelectedTextMessage();
void HandleLoadPreviewPageMessage(const pp::VarDictionary& dict);
void HandlePrintMessage(const pp::VarDictionary& dict);
void HandleResetPrintPreviewModeMessage(const pp::VarDictionary& dict);
void HandleViewportMessage(const pp::VarDictionary& dict);
void ResetRecentlySentFindUpdate(int32_t);
// Called whenever the plugin geometry changes to update the location of the